org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
I'm using Hibernate for all CRUD operations in my project. It doesn't work for One-To-Many and Many-To-One relationships. It gives me the below error.
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
Then again i went through this video tutorial. It is very simple to me, in the beginning. But, i cant make it work. It also now, says
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]
I have ran some searches in the internet, there someone telling its a bug in Hibernate, and some says, by adding @GenereatedValue this error ll be cleared, but it doesn't work for me.
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();
}
}
Console:
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)
The 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>
You are using field access strategy (determined by @Id annotation). Put any JPA related annotation right above each field instead of getter property
@OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
private List<Student> students;
Adding the @ElementCollection
to the List field solved this issue:
@Column
@ElementCollection(targetClass=Integer.class)
private List<Integer> countries;
Problem with Access strategies
As a JPA provider, Hibernate can introspect both the entity attributes (instance fields) or the accessors (instance properties). By default, the placement of the
@Id
annotation gives the default access strategy. When placed on a field, Hibernate will assume field-based access. Placed on the identifier getter, Hibernate will use property-based access.
Field-based access
When using field-based access, adding other entity-level methods is much more flexible because Hibernate won’t consider those part of the persistence state
@Entity
public class Simple {
@Id
private Integer id;
@OneToMany(targetEntity=Student.class, mappedBy="college",
fetch=FetchType.EAGER)
private List<Student> students;
//getter +setter
}
Property-based access
When using property-based access, Hibernate uses the accessors for both reading and writing the entity state
@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;
}
}
But you can't use both Field-based and Property-based access at the same time. It will show like that error for you
For more idea follow this
Just insert the @ElementCollection annotation over your array list variable, as below:
@ElementCollection
private List<Price> prices = new ArrayList<Price>();
I hope this helps
@Access(AccessType.PROPERTY)
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="userId")
public User getUser() {
return user;
}
I have the same problems, I solved it by add @Access(AccessType.PROPERTY)
Though I am new to hibernate but with little research (trial and error we can say) I found out that it is due to inconsistency in annotating the methods/fileds.
when you are annotating @ID on variable make sure all other annotations are also done on variable only and when you are annotating it on getter method same make sure you are annotating all other getter methods only and not their respective variables.
In my case it was stupid missing of @OneToOne annotation, i set @MapsId without it
Don't worry! This problem occurs because of the annotation. Instead of Field based access, Property based access solves this problem. The code as follows:
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;
}
}
In case anyone else lands here with the same issue I encountered. I was getting the same error as above:
Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Collection, at table:
Hibernate uses reflection to determine which columns are in an entity. I had a private method that started with 'get' and returned an object that was also a hibernate entity. Even private getters that you want hibernate to ignore have to be annotated with @Transient. Once I added the @Transient annotation everything worked.
@Transient
private List<AHibernateEntity> getHibernateEntities() {
....
}
Just remove
mappedBy="college" in @OneToMany(targetEntity=Student.class, mappedBy="college", fetch=FetchType.EAGER)
This solve my issue. ;)
Add the schema name to the entity and it will find it. Worked for me!
Neither of the listed solutions worked for me and here is why: I am using entity inheritance with property-access strategy.
@Entity(name = "spec")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula(value = "type")
public abstract class Spec extends BasicEntity { ... }
Two inheritors have a property which is not presented in the super class. One of the inheritor has JoinColumn
and OneToOne
annotations to consolidate Basic
attribute type usage (actually Intellij IDEA highlights the field if it has not appropriate getter with JoinColumn
annotation).
@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;
}
However, the second inheritor doesn't have any annotations for this new property and somehow IDEA doesn't highlight it to warn me about the issue!
@Data
@Entity
@DiscriminatorValue("blob")
public class BlobSpec extends Spec {
private Payload payload;
//^^^^^^^^^^^^^^^^^^^^^^^^ No getter with @JoinColumn! Should be highlighted with static code check!
I was only able to triage the issue by debuging hibernate classes. I found out that my entity doesn't pass validation in MetadataImpl.validate
method. The exception doesn't tell you about it. It only prints the error occurred in the spec
table, which is not a detailed message.
Had the same problem, my issue was that I didn't specify the @Id annotation on the the id field.
When I annotated it, everything ran smoothly.
精彩评论