我将 Hibernate 用于我项目中的所有 CRUD 操作。它不适用于一对多和多对一关系。它给了我以下错误。
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
然后我又经历了这个video tutorial。一开始对我来说很简单。但是,我不能让它工作。现在也是,说
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
我在互联网上进行了一些搜索,有人告诉 its a bug in Hibernate,有人说,通过添加 @GenereatedValue,这个错误将被清除,但它对我不起作用。
学院.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
学生.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
主.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>
@Access(AccessType.FIELD)
(在我的情况下我想使用 FIELD)是唯一解决它的
您正在使用字段访问策略(由 @Id 注释确定)。将任何与 JPA 相关的注释放在每个字段的正上方,而不是 getter 属性
@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
private List<Student> students;
将 @ElementCollection
添加到列表字段解决了这个问题:
@Column
@ElementCollection(targetClass=Integer.class)
private List<Integer> countries;
targetClass
没有必要,因为您提到了列表的类型<Integer>
访问策略问题
作为 JPA 提供者,Hibernate 可以内省实体属性(实例字段)或访问器(实例属性)。默认情况下,@Id 注释的位置提供了默认访问策略。当放置在一个字段上时,Hibernate 将假定基于字段的访问。放置在标识符 getter 上,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
只需在数组列表变量上插入 @ElementCollection 注释,如下所示:
@ElementCollection
private List<Price> prices = new ArrayList<Price>();
我希望这有帮助
@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)是唯一解决它的
就我而言,缺少@OneToOne 注释是愚蠢的,我在没有它的情况下设置了@MapsId
虽然我是hibernate的新手,但几乎没有研究(我们可以说反复试验)我发现这是由于注释方法/文件的不一致造成的。
当您在变量上注释 @ID 时,请确保所有其他注释也仅在变量上完成,并且当您在 getter 方法上对其进行注释时,请确保您仅注释所有其他 getter 方法而不是它们各自的变量。
不用担心!由于注释而出现此问题。而不是基于字段的访问,基于属性的访问解决了这个问题。代码如下:
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;
}
}
以防其他人在这里遇到与我遇到的相同问题。我遇到了与上面相同的错误:
调用 init 方法失败;嵌套异常是 org.hibernate.MappingException:无法确定类型:java.util.Collection,在表:
Hibernate 使用反射来确定实体中的哪些列。我有一个以“get”开头的私有方法,并返回一个也是休眠实体的对象。即使是您希望 hibernate 忽略的私有 getter,也必须使用 @Transient 进行注释。一旦我添加了@Transient 注释,一切就正常了。
@Transient
private List<AHibernateEntity> getHibernateEntities() {
....
}
将架构名称添加到实体中,它会找到它。为我工作!
列出的解决方案都不适合我,原因如下:我将实体继承与属性访问策略结合使用。
@Entity(name = "spec")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula(value = "type")
public abstract class Spec extends BasicEntity { ... }
两个继承者具有超类中没有的属性。继承者之一具有 JoinColumn
和 OneToOne
注释以整合 Basic
属性类型的使用(实际上,如果 Intellij IDEA 没有适当的带有 JoinColumn
注释的 getter,则会突出显示该字段)。
@Data
@Entity
@DiscriminatorValue("data")
public class DataSpec extends Spec {
private Payload payload;
@OneToOne
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "payload_id")
public Payload getPayload() {
return payload;
}
然而,第二个继承者没有对这个新属性的任何注释,并且不知何故 IDEA 没有突出显示它来警告我这个问题!
@Data
@Entity
@DiscriminatorValue("blob")
public class BlobSpec extends Spec {
private Payload payload;
//^^^^^^^^^^^^^^^^^^^^^^^^ No getter with @JoinColumn! Should be highlighted with static code check!
我只能通过调试休眠类来对问题进行分类。我发现我的实体在 MetadataImpl.validate
方法中没有通过验证。例外没有告诉你。它只打印 spec
表中发生的错误,这不是详细消息。
只需删除
@OneToMany 中的 mappedBy="college"(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
这解决了我的问题。 ;)
有同样的问题,我的问题是我没有在 id 字段上指定@Id 注释。
当我注释它时,一切都很顺利。
不定期副业成功案例分享
object references an unsaved transient instance - save the transient instance before flushing
您是否知道此错误。如果不是就离开它。我正在寻找。cascade=CascadeType.ALL
。但对我来说,它在我的日食中显示错误并且没有任何建议。你知道吗? :)persistence.cascade
现在它已清除。但我再次收到旧错误object references an unsaved transient instance - save the transient instance before flushing
任何建议!!! :+|