私は自分のプロジェクトのすべてのCRUD操作にHibernateを使用しています。 1対多および多対1の関係では機能しません。以下のエラーが表示されます。
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)]
私はインターネットでいくつかの検索を実行しましたが、誰かが Hibernateのバグ と言っており、 @ 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>
フィールドアクセス戦略(@Idアノテーションで決定)を使用しています。 getterプロパティの代わりに、JPA関連の注釈を各フィールドのすぐ上に配置します
@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
private List<Student> students;
@ElementCollection
をリストフィールドに追加すると、この問題は解決しました。
@Column
@ElementCollection(targetClass=Integer.class)
private List<Integer> countries;
アクセス戦略の問題
JPAプロバイダーとして、Hibernateはエンティティ属性(インスタンスフィールド)またはアクセサー(インスタンスプロパティ)の両方を内省できます。デフォルトでは、
@Id
アノテーションの配置はデフォルトのアクセス戦略を提供します。フィールドに配置すると、Hibernateはフィールドベースのアクセスを想定します。識別子ゲッターに配置されたHibernateは、プロパティベースのアクセスを使用します。
フィールドベースのアクセス
フィールドベースのアクセスを使用する場合、Hibernateは永続状態のこれらの部分を考慮しないため、他のエンティティレベルのメソッドを追加する方がはるかに柔軟です
@Entity
public class Simple {
@Id
private Integer id;
@OneToMany(targetEntity=Student.class, mappedBy="college",
fetch=FetchType.EAGER)
private List<Student> students;
//getter +setter
}
プロパティベースのアクセス
プロパティベースのアクセスを使用する場合、Hibernateはエンティティー状態の読み取りと書き込みの両方にアクセサーを使用します
@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;
}
}
ただし、フィールドベースのアクセスとプロパティベースのアクセスの両方を同時に使用することはできません。そのようなエラーが表示されます
詳細については、 this を参照してください
@Access(AccessType.PROPERTY)
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="userId")
public User getUser() {
return user;
}
私は同じ問題を抱えています。@Access(AccessType.PROPERTY)
を追加して解決しました
心配しないで!この問題は注釈のために発生します。フィールドベースのアクセスの代わりに、プロパティベースのアクセスがこの問題を解決します。次のようなコード:
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;
}
}
私は冬眠するのは初めてですが、少しの研究(試行錯誤と言える)で、メソッド/フィールドに注釈を付ける際の不整合が原因であることがわかりました。
変数で@IDに注釈を付けるときは、他のすべての注釈も変数でのみ行うようにし、ゲッターメソッドで同じように注釈を付けるときは、それぞれの変数ではなく、他のすべてのゲッターメソッドだけに注釈を付けるようにしてください。