Varlık hatası için eşlemede başka bir Tekrarlanan sütun


112

Diğer tüm gönderilere rağmen, MacOSX, NetBeans 7.2'de GlassFish ile bu hataya bir çözüm bulamıyorum.

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

İşte kod:

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
}

Yanıtlar:


130

Mesaj açık: Eşlemede tekrarlanan bir sütununuz var. Bu, aynı veritabanı sütununu iki kez eşleştirdiğiniz anlamına gelir. Ve gerçekten, sahipsin:

@Column(nullable=false)
private Long customerId;

ve ayrıca:

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

(ve aynı şey productId/ için de geçerlidir product).

Diğer varlıklara kimlikleriyle değil, varlığa doğrudan atıfta bulunarak başvurmalısınız. customerIdAlanı kaldırın, işe yaramaz. Ve aynısını için de yapın productId. Bir satışın müşteri kimliğini istiyorsanız, bunu yapmanız yeterlidir:

sale.getCustomer().getId()

1
Aynı hatayı alıyorum ama durumum biraz farklı. Varlığım, aynı türden bir veya daha fazla varlığın babası olabilir. Çocukların babalarının kimliği ve kendilerine ait benzersiz bir kimlik referansı vardır. Böyle döngüsel bir bağımlılığı nasıl çözebilirim?
Ciri

@JBNizet Öyleyse belirli bir satışı nasıl kaydedebilirimcustomerId ? (örneğin JSON'dan).
Mikhail Batcer

2
Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);
JB Nizet

5
Sınıfın başka bir alanı ile @EmbeddedIdbirleşik anahtarın olduğu durumu nasıl ele alıyorsunuz ? Bu durumda eşlemede her iki sütuna da ihtiyacım var, değil mi? customerIdCustomer
louis amoros

2
@louisamoros Evet, tekrarlıyorsunuz, ancak ekleyin @MapsId("customerId"), bkz. stackoverflow.com/questions/16775055/hibernate-embeddedid-join
Dalibor Filus

71

Birisinin JPA ek açıklamalarını önceden yerleştirdiği ancak ilişkileri tanımlamadığı eski bir veritabanında takılıp kaldıysanız ve şimdi bunları kodunuzda kullanmak üzere tanımlamaya çalışıyorsanız, diğer koddan beri customerId @Column öğesini silemeyebilirsiniz. zaten doğrudan referans olabilir. Bu durumda ilişkileri şu şekilde tanımlayın:

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

Bu, ilişkilere erişmenizi sağlar. Bununla birlikte, ilişkilere eklemek / güncellemek için, yabancı anahtarları, tanımlanmış @Column değerleri aracılığıyla doğrudan değiştirmeniz gerekir. Bu ideal bir durum değil, ancak bu tür bir durumla karşılaşırsanız, en azından JPQL'i başarılı bir şekilde kullanabilmek için ilişkileri tanımlayabilirsiniz.


1
Teşekkürler, bu tam olarak ihtiyacım olan çözüm, ManyToOneharitalama alanının yanı sıra , birleştirme sütununa doğrudan eşlenmiş bir alana ihtiyacım var.
ryenus

Bu, aynı anda hem ön anahtar hem de birincil anahtar olan bir alanınız olduğunda doğru çözümdür.
AntuanSoft

Aman tanrım, günümü kurtarmış olabilirsin ... tam olarak bu dava
Clomez

23

bunu kullan, benim için 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;

Teşekkürler, tam da ihtiyacım olan çözüm bu

İsteğe bağlı = true ile bile çalışır.
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;
}

Zaten bir sütunu eşlediyseniz ve yanlışlıkla aynı değerleri name ve referencedColumnName için @JoinColumn hazırda bekletme modunda ayarladıysanız aynı aptalca hatayı veriyor

Hata:

Nedeni: org.hibernate.MappingException: Varlık için eşlemede tekrarlanan sütun: com.testtest.SomeCustomEntity sütunu: COLUMN_NAME (insert = "false" update = "false" ile eşlenmelidir)


2
Benim için burada önemli bir nokta, hatanın "insert = false update = false" ile eşlenmesi gerektiği, ancak gerçek parametrelerin / yöntemlerin "insertable = false, updatable = false" olması gerektiğiydi.
Night Owl

1

Umarım bu yardımcı olur!

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

0

Herhangi bir özellik için yalnızca 1 ayarlayıcı ve alıcı sağlamaya dikkat edin. Yaklaşmanın en iyi yolu, tüm özniteliklerin tanımını yazmak ve ardından bunu manuel olarak yapmak yerine eclipse generate setter ve getter yardımcı programını kullanmaktır. Seçenek sağ tıklama-> kaynak -> Alıcı ve Ayarlayıcı Oluştur'da gelir.


0

Bu, varlık sınıfınızda bir sütunu iki kez eşleştirdiğiniz anlamına gelir. Bir örnekle açıklamak ...

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

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

Yukarıdaki kod parçasındaki sorun, eşlemeyi tekrarlıyor olmamızdır ...

Çözüm

Haritalama önemli bir parça olduğu için bunu kaldırmak istemezsiniz. Bunun yerine kaldıracaksın

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

Yine de bir TableClass nesnesi oluşturarak ve buna Object1'in String değerini atayarak object1'in değerini iletebilirsiniz.

Bu% 100 çalışır. Bunu Postgres ve Oracle veritabanı ile test ettim.


0

Grails 4'te (GORM) ana varlık yerine alt varlığı eşleyerek döngüsel bağımlılığı (Üst-Alt Varlıklar) çözdük.

Misal:

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]
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.