org.hibernate.MappingException: 无法确定类型: java.util.List,在表: College 的列: [org.hibernate.mapping.Column(students)]。
org.hibernate.MappingException: 无法确定类型: java.util.List,在表: College 的列: [org.hibernate.mapping.Column(students)]。
我在我的项目中使用Hibernate进行所有的CRUD操作。它对于一对多和多对一的关系无效。它给了我以下错误。\norg.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
\n然后我又看了这个视频教程。一开始对我来说很简单。但是,我无法让它工作。它现在也说\norg.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
\n我在互联网上进行了一些搜索,有人说这是Hibernate的一个bug,还有人说通过添加@GenereatedValue可以清除这个错误,但对我来说没有效果。\nCollege.java\n
@Entity public class College { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int collegeId; private String collegeName; private Liststudents; @OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER) public List getStudents() { return students; } public void setStudents(List students) { this.students = students; }//省略其他getter和setter方法
\nStudent.java\n
@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; }//省略其他getter和setter方法
\nMain.java:\n
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(); } }
\nConsole:\n
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)
\nThe XML:\n
com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/dummy root 1234 1 org.hibernate.dialect.MySQLDialect thread org.hibernate.cache.NoCacheProvider true update
问题的原因是在实体类中使用了同时使用了字段访问和属性访问两种方式。在这种情况下,Hibernate无法确定使用哪种访问策略。
解决方法是选择一种访问策略并在实体类中统一使用该策略。可以通过在实体类中的字段上或者属性的getter方法上添加@Access
注解来指定访问策略。
如果要使用字段访问策略,需要在实体类的字段上添加@Access(AccessType.FIELD)
注解。例如:
public class College { private Integer id; @OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER) @Access(AccessType.FIELD) private Liststudents; // getter + setter }
如果要使用属性访问策略,需要在实体类的getter方法上添加@Access(AccessType.PROPERTY)
注解。例如:
public class College { private Integer id; private Liststudents; @Access(AccessType.PROPERTY) public List getStudents() { return students; } public void setStudents(List students) { this.students = students; } // getter + setter }
需要注意的是,不能同时在字段和属性的getter方法上使用@Access
注解,否则会出现上述的异常。在实体类中选择一种访问策略并保持一致即可解决该问题。
更多关于Hibernate访问策略的信息,请参考官方文档。
在上述内容中,出现了一个错误信息:org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]。该错误的原因是在College表中的students列中,无法确定java.util.List的类型。
解决这个问题的方法是,在List字段上添加targetClass
标签,并指定List的类型。例如,将List字段的类型指定为Integer的列表:
(targetClass=Integer.class) private List<Integer> countries;
这样做是因为我们在问题中提到了List的类型为targetClass
标签是必要的。
另外,也有其他解决方法。例如,可以将List字段的类型改为Set
当遇到类似的错误时,我们可以通过添加targetClass
标签来解决问题,或者将List字段的类型改为Set。
问题原因:这个问题的原因是使用了字段访问策略(由注解确定)。将任何JPA相关的注解放在每个字段的上方,而不是getter方法上。
解决方法:将JPA相关的注解放在每个字段的上方,而不是getter方法上。
在这段对话中,某些情况下了另一个错误并给出了解决方法。他们提到了一个链接,链接中提到了使用cascade=CascadeType.ALL
来解决这个错误。但是对于提问者来说,他们在Eclipse中遇到了错误并没有得到任何建议。最后,他们解决了这个问题。
另外,还某些情况下了JPA中的访问策略的一些细节。在JPA 1.0中,不能混合使用字段访问策略和属性访问策略,但在JPA 2.0中可以混合使用,但需要额外的注解。因此,建议在应用程序中选择一种策略并坚持使用。
最后,有人问了在getter方法中放置注解和在变量声明中放置注解之间的区别。