org.hibernate.MappingException:无法确定类型:java.util.List,在表:College,用于列:[org.hibernate.mapping.Column(students)]


96

我正在将Hibernate用于项目中的所有CRUD操作。它不适用于一对多和多对一关系。它给了我下面的错误。

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

学生.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>


1
@All:没人告诉我,Main.java中的代码完全放错了地方:(

问题可能是列表对象的创建
Kemal Duran

1
(后来)在我的春季启动应用程序中,@Access(AccessType.FIELD)(就我而言,我想和FIELD一起使用)是唯一解决此问题的工具
-Scaramouche

Answers:


168

您正在使用字段访问策略(由@Id注释确定)。将任何与JPA相关的注释放在每个字段的上方,而不是getter属性的上方

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

@Arthur Ronald FD Garcia:谢谢,它很棒。但是,该程序现在已被新程序停止。object references an unsaved transient instance - save the transient instance before flushing您是否知道此错误。如果不是,那就离开吧。我正在搜寻。

@Arthur Ronald FD Garcia:大家好,我看到了当前错误的解决方案,我在先前的评论中曾提出过要求。这是链接。stackoverflow.com/questions/1667177/…解决方案包括cascade=CascadeType.ALL。但是对我来说,它显示了错误,并且在日食方面没有任何建议。你对此一无所知。:)

9
@Arthur +1很好的@MaRaVan您可以使用字段访问策略或属性访问策略,但是必须在类层次结构中保持一致,不能混用这些策略,至少在JPA 1.0中不能。尽管JPA 2.0使得混合策略成为可能,但是您将需要额外的注释(因此会更加复杂)。因此,建议选择一种策略并在您的应用程序中坚持使用。参见2.2.2.2。访问类型
Pascal Thivent

@Arthur Ronald FD Garcia:嗯...我已经添加了,persistence.cascade现在清除了。但我再次得到旧错误object references an unsaved transient instance - save the transient instance before flushingAnY建议!!!:+ |

@All:没人告诉我,Main.java中的代码完全放错了地方:(

78

将“”添加@ElementCollection到“列表”字段可解决此问题:

    @Column
    @ElementCollection(targetClass=Integer.class)
    private List<Integer> countries;

5
+ targetClass不是必需的,因为您提到过列表的类型<Integer>
O.Badr

1
似乎有必要,因为我正在寻找确切解决此问题的解决方案,并将@ElementCollection(targetClass = String.class)添加到我的简单字符串列表中即可解决该问题。
Angel O'Sphere

32

访问策略问题

作为JPA提供程序,Hibernate可以同时检查实体属性(实例字段)或访问器(实例属性)。默认情况下,@Id注释的放置提供默认的访问策略。当放在一个字段上时,Hibernate将假定基于字段的访问。Hibernate放在标识符getter上,将使用基于属性的访问。

基于现场的访问

使用基于字段的访问时,添加其他实体级别的方法更加灵活,因为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;
}

}

但是您不能同时使用基于字段的访问和基于属性的访问。它会为您显示该错误

要了解更多想法,请遵循


9
@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一起使用)是唯一解决它的应用程序
-Scaramouche

2

不用担心 发生此问题,因为的注释。基于属性的访问解决了此问题,而不是基于字段的访问。代码如下:

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

}


2

只需在数组列表变量上插入@ElementCollection批注,如下所示:

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

我希望这有帮助


那很棒!它就像一个魅力!其他答案对我不起作用。确实做到了。主要答案只是让我陷入了更多的问题,因此我不得不单独解决这个问题。好答案!
编译器v2

2

就我而言,它是愚蠢的缺少@OneToOne批注,我没有设置@MapsId


1

尽管我是冬眠的新手,但很少进行研究(可以说是反复试验),但我发现这是由于注释方法/字段不一致。

当您在变量上注释@ID时,请确保所有其他注释也仅在变量上完成,而在getter方法上进行注释时,请确保仅在所有其他getter方法上进行注释,而不在它们各自的变量上进行注释。


1

万一其他人因我遇到的同样问题而降落在这里。我收到与上述相同的错误:

调用init方法失败;嵌套的异常是org.hibernate.MappingException:无法确定表的java.util.Collection的类型:

Hibernate使用反射来确定实体中的哪些列。我有一个私有方法,该方法以“ get”开头,并返回一个也是休眠实体的对象。甚至您想要休眠忽略的私有获取器也必须使用@Transient进行注释。添加@Transient批注后,一切正常。

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.