2011-02-03 14 views
37

Tôi đang làm việc trên một cơ sở mã kế thừa với một lược đồ DB hiện có. Mã hiện có sử dụng SQL và PL/SQL để thực hiện các truy vấn trên DB. Chúng tôi đã được giao nhiệm vụ thực hiện một phần nhỏ của dự án cơ sở dữ liệu động cơ bất khả tri (lúc đầu, thay đổi mọi thứ cuối cùng). Chúng tôi đã chọn sử dụng các tệp ánh xạ Hibernate 3.3.2.GA và "* .hbm.xml" (trái ngược với chú thích). Thật không may, không thể thay đổi lược đồ hiện tại vì chúng tôi không thể phục hồi bất kỳ tính năng cũ nào.Làm cách nào để có thể ánh xạ "insert = 'false' update = 'false'" trên thuộc tính khóa-id hỗn hợp cũng được sử dụng trong FK một-nhiều?

Vấn đề tôi đang gặp phải là khi tôi cố gắng lập bản đồ một mối quan hệ một chiều, một chiều, trong đó FK là cũng là một phần của PK tổng hợp. Dưới đây là các lớp và tập tin bản đồ ...

CompanyEntity.java

public class CompanyEntity { 
    private Integer id; 
    private Set<CompanyNameEntity> names; 
    ... 
} 

CompanyNameEntity.java

public class CompanyNameEntity implements Serializable { 
    private Integer id; 
    private String languageId; 
    private String name; 
    ... 
} 

CompanyNameEntity.hbm.xml

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
     "http://www.jboss.org/dtd/hibernate/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping package="com.example"> 

    <class name="com.example.CompanyEntity" table="COMPANY"> 
     <id name="id" column="COMPANY_ID"/> 
     <set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> 
      <key column="COMPANY_ID"/> 
      <one-to-many entity-name="vendorName"/> 
     </set> 
    </class> 

    <class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME"> 
     <composite-id> 
      <key-property name="id" column="COMPANY_ID"/> 
      <key-property name="languageId" column="LANGUAGE_ID"/> 
     </composite-id> 
     <property name="name" column="NAME" length="255"/> 
    </class> 

</hibernate-mapping> 

Mã này chỉ hoạt động tốt cho SELECT và INSERT của một công ty có tên. Tôi gặp phải sự cố khi tôi cố gắng cập nhật và ghi lại hiện có. Tôi nhận được một BatchUpdateException và sau khi xem xét thông qua các bản ghi SQL Tôi thấy Hibernate đã cố gắng làm điều gì đó ngu ngốc ...

update COMPANY_NAME set COMPANY_ID=null where COMPANY_ID=? 

Hibernate đã cố gắng để dis-sư hồ sơ con trước khi cập nhật chúng. Vấn đề là trường này là một phần của PK và không có giá trị. Tôi tìm thấy giải pháp nhanh chóng để làm cho Hibernate không làm điều này là thêm "not-null = 'true'" vào phần tử "key" trong ánh xạ chính. lập bản đồ SO bây giờ có thể trông như thế này ...

CompanyNameEntity.hbm.xml

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
     "http://www.jboss.org/dtd/hibernate/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping package="com.example"> 

    <class name="com.example.CompanyEntity" table="COMPANY"> 
     <id name="id" column="COMPANY_ID"/> 
     <set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> 
      <key column="COMPANY_ID" not-null="true"/> 
      <one-to-many entity-name="vendorName"/> 
     </set> 
    </class> 

    <class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME"> 
     <composite-id> 
      <key-property name="id" column="COMPANY_ID"/> 
      <key-property name="languageId" column="LANGUAGE_ID"/> 
     </composite-id> 
     <property name="name" column="NAME" length="255"/> 
    </class> 

</hibernate-mapping> 

lập bản đồ này cung cấp cho các ngoại lệ ...

org.hibernate.MappingException: Repeated column in mapping for entity: companyName column: COMPANY_ID (should be mapped with insert="false" update="false") 

Vấn đề của tôi bây giờ là tôi đã tryed thêm các thuộc tính này vào phần tử thuộc tính khóa nhưng không được DTD hỗ trợ. Tôi cũng đã cố gắng thay đổi nó thành một yếu tố chính-nhiều-một nhưng nó cũng không hoạt động. Vì vậy ...

Làm cách nào để có thể ánh xạ "insert = 'false' update = 'false'" trên thuộc tính khóa-id tổng hợp cũng được sử dụng trong FK một-nhiều?

+0

Sau khi xem xét các chú thích Hibernate doc, có vẻ như tôi có thể có thể tạo ra các bản đồ mong muốn với các chú thích JPA/Hibernate. Tôi sẽ thử nghiệm với điều này nhiều hơn một chút và đăng kết quả của tôi. –

+0

Ánh xạ mà tôi đang cố gắng chỉ định là KHÔNG thể sử dụng các tệp * .hbm.xml. Cách duy nhất để thực hiện điều này là sử dụng chú thích như đã đề cập trong câu trả lời của mcyalcin dưới đây. –

+1

Tôi đoán bài đăng này có thể giải quyết được sự cố trong cấu hình XML, http://stackoverflow.com/questions/9381029/hibernate-mapping-exception-repeated-column-in-mapping-for-entity –

Trả lời

77

Tôi nghĩ rằng chú thích bạn đang tìm kiếm là:

public class CompanyName implements Serializable { 
//... 
@JoinColumn(name = "COMPANY_ID", referencedColumnName = "COMPANY_ID", insertable = false, updatable = false) 
private Company company; 

Và bạn sẽ có thể sử dụng ánh xạ tương tự trong một hbm.xml như trình bày ở đây (trong 23.4.2):

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-mappings.html

+0

Cảm ơn bạn đã trả lời. Trong liên kết tài liệu JBoss mà bạn cung cấp, nó không chứa bất kỳ ví dụ nào về trường hợp tôi gặp sự cố. Tôi đã thử sử dụng ánh xạ chính xác như cách họ thể hiện và nó vẫn không hiệu quả với tôi. Có vẻ như ánh xạ cụ thể mà tôi đang cố thực hiện không thể thực hiện với thông số DTD HBM hiện tại. Điều đó đang được nói, giải pháp của bạn với chú thích không phải đối mặt với cùng một vấn đề tôi đang gặp phải vì vậy nó là một giải pháp tốt cho bất cứ ai có tùy chọn sử dụng chú thích. Tôi thường khuyên bạn nên chú thích cho tất cả những người có sự lựa chọn. –

+0

Thú vị. Tôi đã chỉ sử dụng chú thích với Hibernate cho đến nay, việc tìm kiếm thuận tiện hơn nhưng tôi nghĩ chức năng chú thích là một tập con của các định nghĩa ánh xạ xml, không phải là cách khác xung quanh. Tôi sẽ fiddle với xmls, cho nếu có thực sự là một chức năng bị thiếu, một lỗi nên được báo cáo. Tôi rất vui vì câu trả lời đã giúp! – mcyalcin

+1

Nhưng nếu tôi muốn chèn và cập nhật, có bất kỳ công việc nào khác xung quanh để thoát khỏi điều này không? Bởi vì tôi cho rằng, insertable = false và updatable = false sẽ không cho phép tôi thay đổi "công ty". – kinshuk4

0

"Dino TW" đã cung cấp liên kết tới nhận xét Hibernate Mapping Exception : Repeated column in mapping for entity có thông tin quan trọng.

Các gợi ý liên kết để cung cấp "inverse = true" trong ánh xạ đã đặt, tôi đã thử nó và nó thực sự hoạt động.Đó là một tình huống hiếm hoi trong đó một phím Set và Composite kết hợp với nhau. Thực hiện nghịch đảo = true, chúng tôi để bản cập nhật chèn & của bảng với khóa Composite để được tự chăm sóc.

Dưới đây có thể là lập bản đồ cần thiết,

<class name="com.example.CompanyEntity" table="COMPANY"> 
    <id name="id" column="COMPANY_ID"/> 
    <set name="names" inverse="true" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> 
     <key column="COMPANY_ID" not-null="true"/> 
     <one-to-many entity-name="vendorName"/> 
    </set> 
</class> 
Các vấn đề liên quan