Kolom Berulang lainnya dalam pemetaan untuk kesalahan entitas

110

Terlepas dari semua posting lain, saya tidak dapat menemukan solusi untuk kesalahan ini dengan GlassFish, di MacOSX, NetBeans 7.2.

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")

Berikut kodenya:

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
}
canardman
sumber

Jawaban:

129

Pesannya jelas: Anda memiliki kolom yang berulang di pemetaan. Itu berarti Anda memetakan kolom database yang sama dua kali. Dan memang, Anda memiliki:

@Column(nullable=false)
private Long customerId;

dan juga:

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

(dan hal yang sama berlaku untuk productId/product ).

Anda tidak boleh merujuk entitas lain dengan ID mereka, tetapi dengan referensi langsung ke entitas. Hapus customerIdbidang, itu tidak berguna. Dan lakukan hal yang sama untuk productId. Jika Anda menginginkan ID pelanggan penjualan, Anda hanya perlu melakukan ini:

sale.getCustomer().getId()
JB Nizet
sumber
1
Saya mendapatkan kesalahan yang sama, tetapi situasi saya sedikit berbeda. Entitas saya dapat menjadi ayah dari satu entitas atau lebih dengan tipe yang sama. Anak-anak memiliki referensi tentang identitas ayah mereka serta identitas unik mereka sendiri. Bagaimana saya bisa mengatasi ketergantungan melingkar seperti itu?
Ciri
@JBNizet Lalu bagaimana saya bisa menyimpan Penjualan dengan beberapa tertentu customerId? (misalnya dari JSON).
Mikhail Batcer
2
Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);
JB Nizet
5
Bagaimana Anda menangani kasus di mana Anda memiliki @EmbeddedIdkunci komposit antara customerIddan bidang lain di Customerkelas? Dalam hal ini saya membutuhkan kedua kolom berulang dalam pemetaan, apakah saya benar?
louis amoros
2
@louisamoros Ya, Anda mengulanginya, tetapi Anda menambahkan @MapsId("customerId"), lihat stackoverflow.com/questions/16775055/hibernate-embeddedid-join
Dalibor Filus
71

Jika Anda terjebak dengan database lawas di mana seseorang telah menempatkan anotasi JPA tetapi TIDAK menentukan hubungannya dan Anda sekarang mencoba untuk menentukannya untuk digunakan dalam kode Anda, maka Anda mungkin TIDAK dapat menghapus customerId @Column karena kode lain dapat langsung merujuknya. Dalam kasus tersebut, tentukan hubungan sebagai berikut:

@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;

Ini memungkinkan Anda untuk mengakses hubungan. Namun, untuk menambah / memperbarui hubungan, Anda harus memanipulasi kunci asing secara langsung melalui nilai @Column yang ditentukan. Ini bukan situasi yang ideal, tetapi jika Anda menghadapi situasi seperti ini, setidaknya Anda dapat menentukan hubungannya sehingga Anda dapat menggunakan JPQL dengan sukses.

pattmatt.dll
sumber
1
Terima kasih, inilah solusi yang saya butuhkan, selain ManyToOnebidang pemetaan, saya memerlukan bidang yang langsung dipetakan ke kolom gabungan.
ryenus
Ini adalah solusi yang tepat bila Anda memiliki bidang yang menjadi kunci depan dan kunci utama pada saat yang bersamaan.
AntuanSoft
Ya Tuhan, Anda mungkin telah menyelamatkan hari saya ... tepatnya kasus ini
Clomez
22

gunakan ini, apakah bekerja untuk saya:

@Column(name = "candidate_id", nullable=false)
private Long candidate_id;
@ManyToOne(optional=false)
@JoinColumn(name = "candidate_id", insertable=false, updatable=false)
private Candidate candidate;
Nomade Redouane
sumber
Terima kasih, inilah solusi yang saya butuhkan
Bekerja bahkan dengan opsional = true.
Ondřej Stašek
11
@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;
}

Jika Anda telah memetakan kolom dan secara tidak sengaja menetapkan nilai yang sama untuk name dan referencedColumnName di @JoinColumn hibernate memberikan kesalahan bodoh yang sama

Kesalahan:

Disebabkan oleh: org.hibernate.MappingException: Kolom berulang dalam pemetaan untuk entitas: com.testtest.SomeCustomEntity kolom: COLUMN_NAME (harus dipetakan dengan insert = "false" update = "false")

dbow
sumber
2
Poin kunci di sini bagi saya adalah bahwa kesalahan mengatakan "harus dipetakan dengan insert = false update = false" tetapi parameter / metode aktual harus "insertable = false, updatable = false".
Night Owl
1

Semoga ini bisa membantu!

@OneToOne(optional = false)
    @JoinColumn(name = "department_id", insertable = false, updatable = false)
    @JsonManagedReference
    private Department department;

@JsonIgnore
    public Department getDepartment() {
        return department;
    }

@OneToOne(mappedBy = "department")
private Designation designation;

@JsonIgnore
    public Designation getDesignation() {
        return designation;
    }
Multi Cabz
sumber
0

Berhati-hatilah untuk menyediakan hanya 1 penyetel dan pengambil untuk atribut apa pun. Cara terbaik untuk melakukan pendekatan adalah dengan menuliskan definisi semua atribut kemudian menggunakan utilitas penyetel dan pengambil gerhana daripada melakukannya secara manual. Opsinya muncul di klik kanan-> source -> Generate Getter and Setter.

romil gaurav
sumber
0

Ini berarti Anda memetakan kolom dua kali di kelas entitas Anda. Menjelaskan dengan contoh ...

    @Column(name = "column1")
    private String object1;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "column1", referencedColumnName = "column1")
    private TableClass object2;

Masalah dalam potongan kode di atas adalah kami mengulangi pemetaan ...

Larutan

Karena pemetaan adalah bagian penting, Anda tidak ingin menghapusnya. Sebaliknya, Anda akan menghapus

    @Column(name = "column1")
    private String uniqueId;

Anda masih bisa meneruskan nilai object1 dengan membuat objek TableClass dan menetapkan nilai String dari Object1 di dalamnya.

Ini berhasil 100%. Saya telah menguji ini dengan database Postgres dan Oracle.

Rishabh Agarwal
sumber
0

Kami telah menyelesaikan ketergantungan melingkar (Entitas Induk-anak) dengan memetakan entitas anak alih-alih entitas induk di Grails 4 (GORM).

Contoh:

Class Person {
    String name
}

Class Employee extends Person{
    String empId
}

//Before my code 
Class Address {
    static belongsTo = [person: Person]
}

//We changed our Address class to:
Class Address {
    static belongsTo = [person: Employee]
}
Vinitha Pukazh Bagya R
sumber