org.hibernate.MappingException: Tidak dapat menentukan jenis untuk: java.util.List, di tabel: College, untuk kolom: [org.hibernate.mapping.Column (siswa)]

97

Saya menggunakan Hibernate untuk semua operasi CRUD dalam proyek saya. Ini tidak berfungsi untuk hubungan One-To-Many dan Many-To-One. Ini memberi saya kesalahan di bawah ini.

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

Kemudian lagi saya melalui tutorial video ini . Ini sangat sederhana bagi saya, pada awalnya. Tapi, saya tidak bisa membuatnya berhasil. Sekarang juga, kata

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

Saya telah menjalankan beberapa pencarian di internet, ada seseorang yang mengatakan bug di Hibernate , dan beberapa mengatakan, dengan menambahkan @GenereatedValue kesalahan ini akan dihapus, tetapi tidak berhasil untuk saya.

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


}

Menghibur:

 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>

Karl Richter
sumber
1
@ All: Tidak ada yang memberi tahu saya tentang, kesalahan penempatan kode di Main.java :(
masalahnya adalah pembuatan objek daftar
Kemal Duran
1
[ribuan tahun kemudian] di aplikasi boot musim semi saya, @Access(AccessType.FIELD)(dalam kasus saya, saya ingin menggunakan FIELD) adalah satu-satunya yang menyelesaikannya
Scaramouche

Jawaban:

176

Anda menggunakan strategi akses bidang (ditentukan oleh anotasi @Id). Letakkan anotasi terkait JPA tepat di atas setiap bidang, bukan properti pengambil

@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
private List<Student> students;
Arthur Ronald
sumber
@Arthur Ronald FD Garcia: Terima kasih, ini berhasil dengan baik. Tapi, program itu sekarang dihentikan oleh program baru. object references an unsaved transient instance - save the transient instance before flushingApakah Anda menyadari kesalahan ini. Jika tidak biarkan saja. Aku sedang mencari.
@Arthur Ronald FD Garcia: Hai lagi, saya melihat solusi untuk kesalahan saya saat ini, yang saya tanyakan di komentar saya sebelumnya. Ini tautannya. stackoverflow.com/questions/1667177/… Solusinya termasuk cascade=CascadeType.ALL. Tapi bagi saya itu menunjukkan kesalahan dan tidak ada saran di gerhana saya. Apakah Anda tahu sesuatu tentang itu. :)
10
@Arthur +1 Penangkapan yang bagus @MaRaVan Anda dapat menggunakan strategi akses lapangan atau strategi akses properti tetapi Anda harus konsisten dalam hierarki kelas, Anda tidak dapat mencampur strategi, setidaknya tidak di JPA 1.0. JPA 2.0 memungkinkan untuk menggabungkan strategi, tetapi Anda memerlukan penjelasan tambahan (dan dengan demikian lebih banyak kerumitan). Jadi rekomendasinya adalah memilih satu strategi dan mematuhinya dalam aplikasi Anda. Lihat 2.2.2.2. Jenis akses .
Pascal Thivent
@Arthur Ronald FD Garcia: Hmmmm ... Saya telah menambahkan persistence.cascadeSekarang sudah dibersihkan. Tetapi saya kembali mendapatkan kesalahan lama object references an unsaved transient instance - save the transient instance before flushingSaran AnY !!! : + |
@ All: Tidak ada yang memberi tahu saya tentang, kesalahan penempatan kode di Main.java :(
79

Menambahkan @ElementCollectionke bidang Daftar memecahkan masalah ini:

    @Column
    @ElementCollection(targetClass=Integer.class)
    private List<Integer> countries;
Biggy_java2
sumber
5
+ targetClasstidak diperlukan karena Anda menyebutkan jenis daftar<Integer>
O.Badr
1
Tampaknya perlu, karena saya sedang mencari solusi untuk masalah ini, dan menambahkan @ElementCollection (targetClass = String.class) ke daftar string sederhana saya menyelesaikannya.
Angel O'Sphere
33

Masalah dengan strategi Access

Sebagai penyedia JPA, Hibernate dapat melakukan introspeksi pada atribut entitas (bidang contoh) atau pengakses (properti contoh). Secara default, penempatan @Idanotasi memberikan strategi akses default. Ketika ditempatkan di lapangan, Hibernate akan mengasumsikan akses berbasis lapangan. Ditempatkan pada pengambil pengenal, Hibernate akan menggunakan akses berbasis properti.

Akses berbasis lapangan

Saat menggunakan akses berbasis lapangan, menambahkan metode tingkat entitas lain jauh lebih fleksibel karena Hibernate tidak akan mempertimbangkan bagian dari status persistensi tersebut

@Entity
public class Simple {

@Id
private Integer id;

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

//getter +setter
}

Akses berbasis properti

Saat menggunakan akses berbasis properti, Hibernate menggunakan pengakses untuk membaca dan menulis status entitas

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

}

Namun Anda tidak dapat menggunakan akses berbasis Lapangan dan Properti secara bersamaan. Ini akan menunjukkan kesalahan seperti itu untuk Anda

Untuk ide lebih lanjut ikuti ini

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

Saya memiliki masalah yang sama, saya menyelesaikannya dengan menambahkan @Access(AccessType.PROPERTY)

pengguna2406031
sumber
di aplikasi boot musim semi saya, @Access(AccessType.FIELD)(dalam kasus saya, saya ingin menggunakan FIELD) adalah satu-satunya yang menyelesaikannya
Scaramouche
2

Jangan khawatir! Masalah ini terjadi karena anotasi. Alih-alih akses berbasis lapangan, akses berbasis properti memecahkan masalah ini. Kodenya sebagai berikut:

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

}

batu harun
sumber
2

Cukup masukkan anotasi @ElementCollection di atas variabel daftar array Anda, seperti di bawah ini:

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

saya harap ini membantu

Renato Vasconcellos
sumber
Itu hebat! Ini bekerja seperti pesona! Jawaban lain tidak berhasil untuk saya. Ini benar-benar berhasil. Jawaban utama hanya membawa saya ke lebih banyak masalah yang harus saya tangani secara terpisah dari yang satu ini. Jawaban yang bagus!
Kompiler v2
1

Meskipun saya baru dalam hibernasi tetapi dengan sedikit penelitian (coba-coba, kami dapat mengatakannya) saya menemukan bahwa itu karena ketidakkonsistenan dalam memberi anotasi metode / file.

ketika Anda membuat anotasi @ID pada variabel, pastikan semua penjelasan lainnya juga dilakukan pada variabel saja dan ketika Anda membuat anotasi pada metode pengambil yang sama, pastikan Anda hanya menganotasi semua metode pengambil lainnya dan bukan variabelnya masing-masing.

ShailendraChoudhary
sumber
1

Seandainya ada orang lain yang mendarat di sini dengan masalah yang sama yang saya temui. Saya mendapatkan kesalahan yang sama seperti di atas:

Pemanggilan metode init gagal; pengecualian bersarang adalah org.hibernate.MappingException: Tidak dapat menentukan jenis untuk: java.util.Collection, di tabel:

Hibernasi menggunakan refleksi untuk menentukan kolom mana yang berada dalam suatu entitas. Saya memiliki metode pribadi yang dimulai dengan 'get' dan mengembalikan objek yang juga merupakan entitas hibernasi. Bahkan getter pribadi yang Anda ingin agar hibernasi diabaikan harus dianotasi dengan @Transient. Setelah saya menambahkan anotasi @Transient, semuanya berfungsi.

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}
jbppsu.dll
sumber
1

Dalam kasus saya itu bodoh karena kehilangan anotasi @OneToOne, saya menetapkan @MapsId tanpa itu

S. Dayneko
sumber