2013-02-25 6 views
56

Mặc dù tất cả các bài đăng khác, tôi không thể tìm thấy giải pháp cho lỗi này với GlassFish, trên MacOSX, NetBeans 7.2.Cột lặp lại khác trong ánh xạ cho lỗi thực thể

Here the error : 
SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer 
prepare method 
SEVERE: Exception while preparing the app 
SEVERE: [PersistenceUnit: supmarket] Unable to build EntityManagerFactory 

... 

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: 
com.supmarket.entity.Sale column: customerId 
(should be mapped with insert="false" update="false") 

Đây mã:

Sale.java

@Entity 
public class Sale { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(nullable=false) 
    private Long idFromAgency; 

    private float amountSold; 

    private String agency; 

    @Temporal(javax.persistence.TemporalType.DATE) 
    private Date createdate; 

    @Column(nullable=false) 
    private Long productId; 

    @Column(nullable=false) 
    private Long customerId; 

    @ManyToOne(optional=false) 
    @JoinColumn(name="productId",referencedColumnName="id_product") 
    private Product product; 

    @ManyToOne(optional=false) 
    @JoinColumn(name="customerId",referencedColumnName="id_customer") 
    private Customer customer; 


    public void Sale(){}  
    public void Sale(Long idFromAgency, float amountSold, String agency 
      , Date createDate, Long productId, Long customerId){   
     ... 
    } 

    // then getters/setters 
} 

Customer.java

@Entity 
public class Customer { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name="id_customer") 
    private Long id_customer; 

    @Column(nullable=false) 
    private Long idFromAgency; 

    private String gender, 
        maritalState, 
        firstname, 
        lastname, 
        incomeLevel; 

    @OneToMany(mappedBy="customer",targetEntity=Sale.class, fetch=FetchType.EAGER) 
    private Collection sales; 


    public void Customer(){} 

    public void Customer(Long idFromAgency, String gender, String maritalState, 
      String firstname, String lastname, String incomeLevel) { 
     ... 
    } 

} 

Product.java

public class Product { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name="id_product") 
    private Long id_product; 

    @Column(nullable=false) 
    private Long idFromAgency; 

    private String name; 

    @OneToMany(mappedBy="product",targetEntity=Sale.class, fetch=FetchType.EAGER) 
    private Collection sales; 

    //constructors + getters +setters 
} 

Trả lời

70

Thông báo rõ ràng: bạn có cột lặp lại trong ánh xạ. Điều đó có nghĩa là bạn đã ánh xạ cùng một cột cơ sở dữ liệu hai lần. Và trên thực tế, bạn có:

@Column(nullable=false) 
private Long customerId; 

và cũng:

@ManyToOne(optional=false) 
@JoinColumn(name="customerId",referencedColumnName="id_customer") 
private Customer customer; 

(và cùng đi cho productId/product).

Bạn không nên tham chiếu các thực thể khác theo ID của chúng, nhưng bằng cách tham chiếu trực tiếp đến thực thể. Loại bỏ trường customerId, nó vô dụng. Và làm tương tự cho productId. Nếu bạn muốn ID khách hàng của bán hàng, bạn chỉ cần làm điều này:

sale.getCustomer().getId() 
+0

tôi nhận được lỗi tương tự, nhưng tình hình của tôi là một chút khác nhau. Thực thể của tôi có thể là cha của một hoặc nhiều thực thể cùng loại. Những đứa trẻ có một tham chiếu về id của cha của họ cũng như một id duy nhất của riêng mình. Làm thế nào tôi có thể giải quyết một phụ thuộc vòng tròn như vậy? – Serban

+0

@Serban Đặt câu hỏi của riêng bạn bằng mã. –

+0

@JBNizet Làm thế nào sau đó tôi có thể * lưu * một Bán với một số 'customerId' cụ thể? (ví dụ: từ JSON). –

33

Nếu bạn đang mắc kẹt với một cơ sở dữ liệu di sản mà ai đó đã đặt chú thích JPA trên nhưng không xác định các mối quan hệ và bây giờ bạn đang cố gắng để xác định chúng để sử dụng trong mã của bạn, thì bạn KHÔNG thể xóa customerId @Column vì mã khác có thể trực tiếp tham chiếu nó. Trong trường hợp đó, hãy xác định các mối quan hệ như sau:

@ManyToOne(optional=false) 
@JoinColumn(name="productId",referencedColumnName="id_product", insertable=false, updatable=false) 
private Product product; 

@ManyToOne(optional=false) 
@JoinColumn(name="customerId",referencedColumnName="id_customer", insertable=false, updatable=false) 
private Customer customer; 

Điều này cho phép bạn truy cập các mối quan hệ. Tuy nhiên, để thêm/cập nhật các mối quan hệ, bạn sẽ có thao tác khóa ngoại trực tiếp thông qua các giá trị @Column đã xác định của chúng. Nó không phải là một tình huống lý tưởng, nhưng nếu bạn được giao loại tình huống này, ít nhất bạn có thể định nghĩa các mối quan hệ để bạn có thể sử dụng thành công JPQL.

+0

Cảm ơn, đây chính xác là giải pháp tôi cần , ngoài trường ánh xạ 'ManyToOne', tôi cần một trường được ánh xạ trực tiếp tới cột kết nối. – ryenus

+0

Đây là giải pháp phù hợp khi bạn có một trường đồng thời khóa và khóa chính. – AntuanSoft

7
@Id 
@Column(name = "COLUMN_NAME", nullable = false) 
public Long getId() { 
    return id; 
} 

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = SomeCustomEntity.class) 
@JoinColumn(name = "COLUMN_NAME", referencedColumnName = "COLUMN_NAME", nullable = false, updatable = false, insertable = false) 
@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.ALL) 
public List<SomeCustomEntity> getAbschreibareAustattungen() { 
    return abschreibareAustattungen; 
} 

Nếu bạn đã ánh xạ một cột và đã vô tình đặt các giá trị tương tự cho tênreferencedColumnName trong @JoinColumn Hibernate cung cấp cho các lỗi ngớ ngẩn cùng

Lỗi:

Gây ra bởi: org.hibernate.MappingException: Cột lặp lại trong ánh xạ cho thực thể: cột com.testtest.SomeCustomEntity: COLUMN_NAME (nên được ánh xạ với ert = "false" update = "false")

+0

Một điểm quan trọng ở đây cho tôi là lỗi nói "nên được ánh xạ với insert = false update = false" nhưng các tham số/phương thức thực tế phải là "insertable = false, updatable = false". –

0

Cẩn thận chỉ cung cấp 1 setter và getter cho bất kỳ thuộc tính nào.Cách tốt nhất để tiếp cận là viết ra định nghĩa của tất cả các thuộc tính sau đó sử dụng eclipse tạo setter và tiện ích getter thay vì làm nó theo cách thủ công. Tùy chọn xuất hiện trên nhấp chuột phải-> nguồn -> Tạo Getter và Setter.

4

sử dụng này, là một công việc cho tôi:

@Column(name = "candidate_id", nullable=false) 
private Long candidate_id; 
@ManyToOne(optional=false) 
@JoinColumn(name = "candidate_id", insertable=false, updatable=false) 
private Candidate candidate; 
+0

Cảm ơn, đây chính xác là giải pháp tôi cần –