org.hibernate.MappingException: java.util.List, टेबल पर: कॉलम के लिए, कॉलेज: [org.hibernate.mapping.Column (छात्र)] के लिए टाइप का निर्धारण नहीं किया जा सकता है।


96

मैं अपने प्रोजेक्ट में सभी CRUD ऑपरेशन के लिए हाइबरनेट का उपयोग कर रहा हूं। यह एक-से-कई और कई-से-एक रिश्तों के लिए काम नहीं करता है। यह मुझे नीचे त्रुटि देता है।

org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]

फिर मैं इस वीडियो ट्यूटोरियल के माध्यम से चला गया । यह मेरे लिए बहुत सरल है, शुरुआत में। लेकिन, मैं यह काम नहीं कर सकते। यह भी अब, कहते हैं

org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]

मैंने इंटरनेट में कुछ खोजों को चलाया है, वहां किसी ने हाइबरनेट में एक बग बताया है , और कुछ कहते हैं, @GenereatedValue जोड़कर यह त्रुटि स्पष्ट हो जाएगी, लेकिन यह मेरे लिए काम नहीं करता है।

College.java

@Entity
public class College {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int collegeId;
private String collegeName;


private List<Student> students;

@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
public List<Student> getStudents() {
    return students;
}
public void setStudents(List<Student> students) {
    this.students = students;
}//Other gettters & setters omitted

Student.java

@Entity
public class Student {


@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int studentId;
private String studentName;


private College college;

@ManyToOne
@JoinColumn(name="collegeId")
public College getCollege() {
    return college;
}
public void setCollege(College college) {
    this.college = college;
}//Other gettters & setters omitted

Main.java:

public class Main {

private static org.hibernate.SessionFactory sessionFactory;

  public static SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
      initSessionFactory();
    }
    return sessionFactory;
  }

  private static synchronized void initSessionFactory() {
    sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

  }

  public static Session getSession() {
    return getSessionFactory().openSession();
  }

  public static void main (String[] args) {
                Session session = getSession();
        Transaction transaction = session.beginTransaction();
        College college = new College();
        college.setCollegeName("Dr.MCET");

        Student student1 = new Student();
        student1.setStudentName("Peter");

        Student student2 = new Student();
        student2.setStudentName("John");

        student1.setCollege(college);
        student2.setCollege(college);



        session.save(student1);
        session.save(student2);
        transaction.commit();
  }


}

कंसोल:

 Exception in thread "main" org.hibernate.MappingException: Could not determine type  for: java.util.List, at table: College, for columns:  [org.hibernate.mapping.Column(students)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:306)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:290)
at org.hibernate.mapping.Property.isValid(Property.java:217)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:463)
at org.hibernate.mapping.RootClass.validate(RootClass.java:235)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1330)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1833)
at test.hibernate.Main.initSessionFactory(Main.java:22)
at test.hibernate.Main.getSessionFactory(Main.java:16)
at test.hibernate.Main.getSession(Main.java:27)
at test.hibernate.Main.main(Main.java:43)

XML:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <!-- Database connection settings -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/dummy</property>
    <property name="connection.username">root</property>
    <property name="connection.password">1234</property>
    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>
    <!-- SQL dialect -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>
    <!-- Disable the second-level cache -->
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>
    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">update</property>

    <mapping class="test.hibernate.Student" />
    <mapping class="test.hibernate.College" />
</session-factory>


1
@ सभी: मेरे बारे में किसी ने नहीं बताया, Main.java में पूरी तरह से गलत कोड कोड :(

समस्या सूची वस्तु का निर्माण हो सकता है
केमल डरान

1
[बाद में] मेरे वसंत बूट ऐप में, @Access(AccessType.FIELD)(मेरे मामले में मैं FIELD के साथ जाना चाहता था) केवल एक ही था जिसने इसे हल किया
स्कारामोच

जवाबों:


168

आप फ़ील्ड एक्सेस रणनीति (@Id एनोटेशन द्वारा निर्धारित) का उपयोग कर रहे हैं । किसी भी जेपीए से संबंधित एनोटेशन को गेट्टर प्रॉपर्टी के बजाय प्रत्येक क्षेत्र के ठीक ऊपर रखें

@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
private List<Student> students;

@ आर्थर रोनाल्ड एफडी गार्सिया: धन्यवाद, इसने बहुत अच्छा काम किया। लेकिन, अब इस कार्यक्रम को नए सिरे से रोक दिया गया है। object references an unsaved transient instance - save the transient instance before flushingक्या आप इस त्रुटि के बारे में जानते हैं। यदि नहीं तो छोड़ दें। मैं ढूंढ रहा हूं।

@ आर्थर रोनाल्ड एफडी गार्सिया: हाय फिर, मैंने अपनी वर्तमान त्रुटि के लिए समाधान देखा, जो मैंने अपनी पिछली टिप्पणी में पूछा था। यहीं वह लिंक है। stackoverflow.com/questions/1667177/… समाधान शामिल है cascade=CascadeType.ALL। लेकिन मेरे लिए यह मेरे ग्रहण में त्रुटि और कोई सुझाव नहीं दिखाता है। अपको इस बारे में कुछ पता है। :)

9
@Aththur +1 अच्छा कैच @MaRVan आप फील्ड एक्सेस स्ट्रैटेजी या प्रॉपर्टी एक्सेस स्ट्रैटेजी का उपयोग कर सकते हैं लेकिन आपको क्लास पदानुक्रम के अनुरूप होना चाहिए, आप रणनीतियों को नहीं मिला सकते, कम से कम जेपीए 1.0 में नहीं। JPA 2.0 हालांकि रणनीतियों को मिलाना संभव बनाता है, लेकिन आपको अतिरिक्त एनोटेशन (और इस प्रकार अधिक जटिलता) की आवश्यकता होगी। तो सिफारिश एक रणनीति चुनने और इसे अपने आवेदन में रखने के लिए है। २.२.२.२ देखें पहुंच प्रकार
पास्कल थिवेंट

@ आर्थर रोनाल्ड एफडी गार्सिया: हम्मम ... मैंने persistence.cascadeअब इसका क्लीयर जोड़ा है । लेकिन मैं फिर से पुरानी त्रुटि प्राप्त करें object references an unsaved transient instance - save the transient instance before flushingसुझाव! : + |

@ सभी: मेरे बारे में किसी ने नहीं बताया, Main.java में पूरी तरह से गलत कोड कोड :(

78

@ElementCollectionसूची फ़ील्ड में जोड़ना इस समस्या को हल करता है:

    @Column
    @ElementCollection(targetClass=Integer.class)
    private List<Integer> countries;

5
+ targetClassआवश्यक नहीं है क्योंकि आपने सूची के प्रकार का उल्लेख किया है<Integer>
O.Badr

1
यह आवश्यक प्रतीत होता है, क्योंकि मैं वास्तव में इस समस्या के लिए एक समाधान खोज रहा था, और तार की मेरी सरल सूची में @ElementCollection (targetClass = String.class) जोड़कर इसे हल किया।
एंजेल ओ स्फीयर

32

प्रवेश रणनीतियों के साथ समस्या

एक जेपीए प्रदाता के रूप में, हाइबरनेट दोनों इकाई विशेषताओं (उदाहरण फ़ील्ड) या एक्सेसर्स (उदाहरण गुण) को आत्मनिरीक्षण कर सकता है। डिफ़ॉल्ट रूप से, @Idएनोटेशन का स्थान डिफ़ॉल्ट एक्सेस रणनीति देता है। जब एक क्षेत्र पर रखा जाता है, तो हाइबरनेट क्षेत्र-आधारित पहुंच ग्रहण करेगा। पहचानकर्ता गेट पर रखा गया, हाइबरनेट संपत्ति-आधारित पहुंच का उपयोग करेगा।

क्षेत्र-आधारित पहुंच

फ़ील्ड-आधारित पहुंच का उपयोग करते समय, अन्य इकाई-स्तरीय विधियों को जोड़ना अधिक लचीला होता है क्योंकि हाइबरनेट दृढ़ता वाले राज्य के उन हिस्से पर विचार नहीं करेगा।

@Entity
public class Simple {

@Id
private Integer id;

@OneToMany(targetEntity=Student.class, mappedBy="college", 
fetch=FetchType.EAGER)
private List<Student> students;

//getter +setter
}

संपत्ति-आधारित पहुंच

संपत्ति-आधारित पहुंच का उपयोग करते समय, हाइबरनेट इकाई राज्य को पढ़ने और लिखने दोनों के लिए एक्सेसरों का उपयोग करता है

@Entity
public class Simple {

private Integer id;
private List<Student> students;

@Id
public Integer getId() {
    return id;
}

public void setId( Integer id ) {
    this.id = id;
}
@OneToMany(targetEntity=Student.class, mappedBy="college", 
fetch=FetchType.EAGER)
public List<Student> getStudents() {
   return students;
}
public void setStudents(List<Student> students) {
    this.students = students;
}

}

लेकिन आप एक ही समय में फ़ील्ड-आधारित और संपत्ति-आधारित पहुँच दोनों का उपयोग नहीं कर सकते। यह आपके लिए उस त्रुटि की तरह दिखाई देगा

अधिक विचार के लिए इसे फॉलो करें


9
@Access(AccessType.PROPERTY)
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="userId")
public User getUser() {
    return user;
}

मेरी वही समस्याएं हैं, मैंने इसे जोड़कर हल किया @Access(AccessType.PROPERTY)


मेरे स्प्रिंग बूट ऐप में, @Access(AccessType.FIELD)(मेरे मामले में मैं FIELD के साथ जाना चाहता था) केवल एक था जिसने इसे हल किया
स्कारामोच

2

चिंता मत करो! एनोटेशन के कारण यह समस्या होती है। फ़ील्ड आधारित पहुँच के बजाय, गुण आधारित पहुँच इस समस्या को हल करती है। कोड निम्नानुसार है:

package onetomanymapping;

import java.util.List;

import javax.persistence.*;

@Entity
public class College {
private int collegeId;
private String collegeName;
private List<Student> students;

@OneToMany(targetEntity = Student.class, mappedBy = "college", 
    cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Student> getStudents() {
    return students;
}

public void setStudents(List<Student> students) {
    this.students = students;
}

@Id
@GeneratedValue
public int getCollegeId() {
    return collegeId;
}

public void setCollegeId(int collegeId) {
    this.collegeId = collegeId;
}

public String getCollegeName() {
    return collegeName;
}

public void setCollegeName(String collegeName) {
    this.collegeName = collegeName;
}

}


2

नीचे दिए गए अनुसार अपनी सरणी सूची चर पर @ElementCollection एनोटेशन डालें:

@ElementCollection
private List<Price> prices = new ArrayList<Price>();

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


एक दम बढ़िया! इसने एक जादू की तरह काम किया! अन्य उत्तर मेरे लिए काम नहीं करते हैं। यह वास्तव में यह किया था। मुख्य उत्तर बस मुझे और अधिक समस्याओं में मिला, जिन्हें मुझे इस एक से अलग करना था। अच्छा उत्तर!
संकलक v2

2

मेरे मामले में यह @OneToOne एनोटेशन से गायब था, मैंने इसके बिना @MapsId सेट किया


1

हालांकि मैं हाइबरनेट करने के लिए नया हूं, लेकिन थोड़ा अनुसंधान (परीक्षण और त्रुटि हम कह सकते हैं) के साथ मुझे पता चला कि यह विधियों / दाखिलों को रद्द करने में असंगति के कारण है।

जब आप वेरिएबल पर @ID एनोटेट कर रहे हैं, तो सुनिश्चित करें कि अन्य सभी एनोटेशन भी केवल वेरिएबल पर ही किए जाते हैं और जब आप इसे गेट्टर मेथड पर एनोटेट कर रहे होते हैं, तो सुनिश्चित करें कि आप केवल अन्य सभी गेट्टर मेथड को एनोटेट कर रहे हैं, न कि उनके संबंधित वैरिएबल को।


1

इस मामले में किसी और के यहाँ भी उसी मुद्दे के साथ जो मैंने सामना किया। मुझे ऊपर जैसी त्रुटि मिल रही थी:

Init विधि का आह्वान विफल; नेस्टेड अपवाद है org.hibernate.MappingException: इसके लिए प्रकार का निर्धारण नहीं किया जा सकता है: java.util.Collection, टेबल पर:

हाइबरनेट एक इकाई में कौन से कॉलम हैं यह निर्धारित करने के लिए प्रतिबिंब का उपयोग करता है। मेरे पास एक निजी तरीका था जो 'get' से शुरू हुआ था और एक ऐसी वस्तु लौटा दी जो हाइबरनेट इकाई भी थी। यहां तक ​​कि निजी गेटर्स जो आप हाइबरनेट को अनदेखा करना चाहते हैं, उन्हें @ ट्रान्सिएंट के साथ एनोटेट करना होगा। एक बार जब मैंने @Transient एनोटेशन जोड़ा तो सब कुछ काम कर गया।

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.