इकाई त्रुटि के लिए मैपिंग में एक और दोहराया स्तंभ


111

अन्य सभी पोस्ट के बावजूद, मैं MacOSX, NetBeans 7.2 पर GlassFish के साथ इस त्रुटि का हल नहीं ढूंढ सकता।

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

यहाँ कोड है:

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
}

जवाबों:


130

संदेश स्पष्ट है: आपके पास मैपिंग में एक दोहराया कॉलम है। इसका मतलब है कि आपने एक ही डेटाबेस कॉलम को दो बार मैप किया है। और वास्तव में, आपके पास:

@Column(nullable=false)
private Long customerId;

और भी:

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

(और वही productId/ के लिए चला जाता है product)।

आपको उनकी आईडी से अन्य संस्थाओं का संदर्भ नहीं देना चाहिए, लेकिन इकाई के प्रत्यक्ष संदर्भ द्वारा। customerIdफ़ील्ड निकालें , यह बेकार है। और उसी के लिए करते हैं productId। यदि आप बिक्री के ग्राहक आईडी चाहते हैं, तो आपको बस यह करने की आवश्यकता है:

sale.getCustomer().getId()

1
मुझे एक ही त्रुटि मिलती है, लेकिन मेरी स्थिति थोड़ी अलग है। मेरी इकाई एक ही प्रकार के एक या अधिक संस्थाओं का पिता हो सकती है। बच्चों के पास अपने पिता की आईडी के साथ-साथ उनकी खुद की एक अनूठी आईडी का संदर्भ है। मैं इस तरह के एक परिपत्र निर्भरता को कैसे हल कर सकता हूं?
गिरि

@JBNizet मैं कैसे कर सकते हैं तो बचाने के कुछ विशेष के साथ एक बिक्री customerId? (जैसे JSON से)।
मिखाइल बैटसर

2
Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);
बजे जेबी निज़ेट

5
आप उस मामले को कैसे संभालते हैं जहां आपके पास कक्षा के किसी अन्य क्षेत्र के @EmbeddedIdबीच एक समग्र कुंजी है ? इस मामले में मुझे मैपिंग में दोनों दोहराया कॉलम की आवश्यकता है, क्या मैं सही हूं? customerIdCustomer
लूइस अमोरोस

2
@louisamoros हाँ, आप इसे दोहराने, लेकिन आप को जोड़ने के @MapsId("customerId")लिए, देखें stackoverflow.com/questions/16775055/hibernate-embeddedid-join
डैलिबर Filus

71

यदि आप एक विरासत डेटाबेस के साथ फंस गए हैं, जहां किसी ने पहले से ही जेपीए एनोटेशन रखा था, लेकिन रिश्तों को परिभाषित नहीं किया था और अब आप उन्हें अपने कोड में उपयोग करने के लिए परिभाषित करने की कोशिश कर रहे हैं, तो आप अपने कोड के बाद से customerId @ कॉलम को हटाने में सक्षम नहीं हो सकते हैं यह सीधे पहले से ही संदर्भित हो सकता है। उस मामले में, रिश्तों को इस प्रकार परिभाषित करें:

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

इससे आप रिश्तों तक पहुंच बना सकते हैं। हालाँकि, रिश्तों को जोड़ने / अपडेट करने के लिए आपको विदेशी कुंजी को सीधे उनके परिभाषित @ कॉलम के माध्यम से हेरफेर करना होगा। यह एक आदर्श स्थिति नहीं है, लेकिन यदि आपको इस तरह की स्थिति सौंपी जाती है, तो कम से कम आप रिश्तों को परिभाषित कर सकते हैं ताकि आप JPQL का सफलतापूर्वक उपयोग कर सकें।


1
धन्यवाद, यह ठीक वही समाधान है जिसकी मुझे आवश्यकता है, ManyToOneमैपिंग फ़ील्ड के अलावा , मुझे सीधे कॉलम से जुड़ने के लिए फ़ील्ड की आवश्यकता है।
रेनस

यह सही समाधान है जब आपके पास एक फ़ील्ड है जो एक ही समय में कुंजी और प्राथमिक कुंजी का समर्थन कर रहा है।
एंटुआनसॉफ्ट

हे भगवान, आपने मेरा दिन बचाया हो सकता है ... बिल्कुल इस मामले में
क्लोमेज़

22

इस का उपयोग करें, मेरे लिए काम है:

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

धन्यवाद, यह वास्तव में मेरे लिए आवश्यक समाधान है

वैकल्पिक = सत्य के साथ भी काम करता है।
ओन्डेज स्टेक

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

आप पहले से ही एक स्तंभ मैप किया गया है और गलती से के लिए एक ही मूल्यों को निर्धारित किया है, तो नाम और referencedColumnName में @JoinColumn हाइबरनेट ही बेवकूफ त्रुटि देता है

त्रुटि:

इसके कारण: org.hibernate.MappingException: एंटिटी के लिए मैपिंग में बार-बार कॉलम: com.testtest.SomeCustomEntity कॉलम: COLUMN_NAME (इंसर्ट के साथ मैप किया जाना चाहिए = "गलत" अपडेट = "गलत")


2
मेरे लिए यहाँ एक महत्वपूर्ण बिंदु यह था कि त्रुटि यह कहती है कि "इन्सर्ट के साथ मैप किया जाना चाहिए = गलत अपडेट = गलत" लेकिन वास्तविक पैरामीटर / तरीके "इंसर्टेबल = गलत, अपडेट करने योग्य = गलत" होने चाहिए।
नाइट उल्लू

1

आशा है कि यह मदद करेगा!

@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

किसी भी विशेषता के लिए केवल 1 सेटर और गेट्टर प्रदान करने का ध्यान रखें। एप्रोच का सबसे अच्छा तरीका है कि सभी विशेषताओं की परिभाषा लिख ​​दी जाए, फिर ग्रहण उत्पन्न करने वाले सेटर और गेटटर उपयोगिता का उपयोग मैन्युअल रूप से करने के बजाय करें। विकल्प राइट क्लिक पर आता है-> स्रोत -> जनरेट गेट्टर और सेटर।


0

इसका मतलब है कि आप अपनी इकाई कक्षा में दो बार एक कॉलम मैप कर रहे हैं। एक उदाहरण के साथ समझाते हुए ...

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

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

उपरोक्त कोड स्निपेट में समस्या यह है कि हम मानचित्रण दोहरा रहे हैं ...

उपाय

चूंकि मैपिंग एक महत्वपूर्ण हिस्सा है, आप इसे हटाना नहीं चाहते हैं। इसके बजाय, आप हटा देंगे

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

आप TableClass का ऑब्जेक्ट बनाकर ऑब्जेक्ट 1 का मान अभी भी पास कर सकते हैं और उसमें Object1 का स्ट्रिंग मान असाइन कर सकते हैं।

यह 100% काम करता है। मैंने इसे Postgres और Oracle डेटाबेस के साथ परीक्षण किया है।


0

हमने ग्रिल्स 4 (जीओआरएम) में मूल इकाई के बजाय बाल इकाई की मैपिंग करके परिपत्र निर्भरता (पेरेंट-चाइल्ड एंटिटीज) को हल किया है।

उदाहरण:

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]
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.