org.hibernate.MappingException: Tür belirlenemedi: java.util.List, tabloda: Kolej, sütunlar için: [org.hibernate.mapping.Column (öğrenciler)]


97

Projemdeki tüm CRUD işlemleri için Hazırda Bekletme kullanıyorum. Bire Çok ve Çoka Bir ilişkiler için işe yaramaz. Bana aşağıdaki hatayı veriyor.

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

Sonra tekrar bu video eğitiminden geçtim . Başlangıçta benim için çok basit. Ama çalışmasını sağlayamıyorum. Şimdi de diyor

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

İnternette bazı aramalar yaptım, biri Hibernate'de bir hata olduğunu söylüyor ve bazıları @GenereatedValue ekleyerek bu hatanın temizleneceğini söylüyor , ancak benim için çalışmıyor.

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


}

Konsol:

 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
@All: Kimse bana Main.java'daki mutlak kodun yanlış yerleştirilmesinden bahsetmedi :(

sorun liste nesnesinin oluşturulması olabilir
Kemal Duran

1
[eons sonra], ilkbahar önyükleme uygulamamda @Access(AccessType.FIELD)(benim durumumda FIELD ile gitmek istedim) sorunu çözen tek şeydi
Scaramouche

Yanıtlar:


176

Alan erişim stratejisini kullanıyorsunuz (@Id ek açıklaması ile belirlenir). Alıcı özelliği yerine, JPA ile ilgili herhangi bir ek açıklamayı her alanın hemen üstüne yerleştirin

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

@Arthur Ronald FD Garcia: Teşekkürler, harika çalıştı. Ancak, program artık yenisi tarafından durdurulmuştur. object references an unsaved transient instance - save the transient instance before flushingBu hatanın farkında mısınız? Bırakmazsan. Arıyorum.

@Arthur Ronald FD Garcia: Tekrar merhaba, önceki yorumumda sorduğum mevcut hatamın çözümünü gördüm. Bağlantı bu. stackoverflow.com/questions/1667177/… Çözüm dahil cascade=CascadeType.ALL. Ama benim için tutulmamda hata gösteriyor ve hiçbir öneri yok. Bunun hakkında bir şey biliyor musun? :)

10
@Arthur +1 İyi yakalama @MaRaVan Alan erişim stratejisini veya mülk erişim stratejisini kullanabilirsiniz, ancak bir sınıf hiyerarşisi içinde tutarlı olmanız gerekir, stratejileri karıştıramazsınız, en azından JPA 1.0'da değil. JPA 2.0, stratejileri karıştırmayı mümkün kılar, ancak fazladan ek açıklamalara (ve dolayısıyla daha fazla karmaşıklığa) ihtiyacınız olacaktır. Bu nedenle, öneri, bir strateji seçmek ve uygulamanızda ona bağlı kalmaktır. Bkz. 2.2.2.2. Erişim türü .
Pascal Thivent

@Arthur Ronald FD Garcia: Hmmmm ... persistence.cascadeŞimdi ekledim , temizlendi. Ama yine eski hatayı object references an unsaved transient instance - save the transient instance before flushingANY Önerileri alıyorum !!! : + |

@All: Kimse bana Main.java'daki mutlak kodun yanlış yerleştirilmesinden bahsetmedi :(

79

@ElementCollectionList alanına eklenmesi bu sorunu çözdü:

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

5
targetClassListenin türünden bahsettiğiniz için + gerekli değildir<Integer>
O.Badr

1
Gerekli gibi görünüyor, çünkü tam olarak bu problem için bir çözüm arıyordum ve @ElementCollection (targetClass = String.class) 'ı basit dizeler listeme ekleyerek çözdüm.
Angel O'Sphere

33

Erişim stratejileriyle ilgili sorun

Bir JPA sağlayıcısı olarak Hibernate, hem varlık özniteliklerini (örnek alanları) hem de erişimcileri (örnek özellikleri) iç gözlem yapabilir. Varsayılan olarak, @Idek açıklamanın yerleştirilmesi varsayılan erişim stratejisini verir. Bir alana yerleştirildiğinde, Hazırda Bekletme, alan tabanlı erişimi üstlenir. Tanımlayıcı alıcıya yerleştirilen Hibernate, mülke dayalı erişimi kullanacaktır.

Alan tabanlı erişim

Alan tabanlı erişimi kullanırken, diğer varlık düzeyinde yöntemler eklemek çok daha esnektir çünkü Hazırda Bekletme, kalıcılık durumunun bu bölümlerini dikkate almaz

@Entity
public class Simple {

@Id
private Integer id;

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

//getter +setter
}

Mülkiyet tabanlı erişim

Mülk tabanlı erişim kullanılırken, Hibernate erişimcileri varlık durumunu hem okumak hem de yazmak için kullanır

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

}

Ancak aynı anda hem Alan tabanlı hem de Mülk tabanlı erişimi kullanamazsınız. Senin için o hatayı gösterecek

Daha fazla fikir için bunu takip edin


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

Ben de aynı sorunları yaşıyorum, ekleyerek çözdüm @Access(AccessType.PROPERTY)


İlkbahar önyükleme uygulamamda @Access(AccessType.FIELD)(benim durumumda FIELD ile gitmek istedim) sorunu çözen tek şeydi
Scaramouche

2

Merak etmeyin! Bu sorun, ek açıklama nedeniyle oluşur. Alan tabanlı erişim yerine, Mülk tabanlı erişim bu sorunu çözmektedir. Kod aşağıdaki gibidir:

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

Aşağıdaki gibi, dizi listesi değişkeninizin üzerine @ElementCollection ek açıklamasını eklemeniz yeterlidir:

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

Umarım bu yardımcı olur


Bu harika! Büyüleyici çalıştı! Diğer cevaplar benim için işe yaramıyor. Bu gerçekten yaptı. Ana cevap beni bundan ayrı olarak ele almam gereken daha fazla soruna soktu. İyi cevap!
Derleyici v2

1

Hazırda bekletmek için yeni olmama rağmen, ancak çok az araştırmayla (deneme yanılma diyebiliriz), bunun yöntemlere / dosyalara açıklama eklemedeki tutarsızlıktan kaynaklandığını öğrendim.

Değişken üzerine @ID eklediğinizde, diğer tüm açıklamaların da yalnızca değişken üzerinde yapıldığından ve alıcı yöntemine açıklama eklediğinizde aynı şekilde diğer tüm alıcı yöntemlerine açıklama eklediğinizden ve ilgili değişkenlerine değil, not aldığınızdan emin olun.


1

Karşılaştığım sorunla başka birinin buraya gelmesi durumunda. Yukarıdakiyle aynı hatayı alıyordum:

İnit yönteminin çağrılması başarısız oldu; iç içe geçmiş istisna, org.hibernate.MappingException: java.util.Collection için tür belirlenemedi, tabloda:

Hazırda bekletme, bir varlıkta hangi sütunların olduğunu belirlemek için yansımayı kullanır. 'Get' ile başlayan ve aynı zamanda hazırda bekletilen bir varlık olan bir nesne döndüren özel bir yöntemim vardı. Hazırda bekletmeyi göz ardı etmek istediğiniz özel alıcılar bile @Transient ile açıklanmalıdır. @Transient ek açıklamasını ekledikten sonra her şey çalıştı.

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}

1

Benim durumumda @OneToOne ek açıklamasının eksik olması aptalca, @MapsId'i onsuz ayarladım

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.