org.hibernate.MappingException: Không thể xác định loại cho: java.util.List, tại bảng: College, cho các cột: [org.hibernate.mapping.Column (sinh viên)]


96

Tôi đang sử dụng Hibernate cho tất cả các hoạt động CRUD trong dự án của mình. Nó không hoạt động cho các mối quan hệ Một-Nhiều và Nhiều-Một. Nó cung cấp cho tôi lỗi bên dưới.

org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]

Sau đó, một lần nữa tôi đã xem qua video hướng dẫn này . Nó rất đơn giản đối với tôi, lúc ban đầu. Nhưng, tôi không thể làm cho nó hoạt động. Nó cũng bây giờ, nói

org.hibernate.MappingException: Could not determine type for: java.util.List, at table: College, for columns: [org.hibernate.mapping.Column(students)]

Tôi đã chạy một số tìm kiếm trên internet, có người nói rằng nó có lỗi trong Hibernate , và một số người nói, bằng cách thêm @GeneratedValue , lỗi này sẽ được xóa, nhưng nó không hoạt động với tôi.

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


}

Bảng điều khiể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)

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: Không ai nói với tôi về việc sai mã hoàn toàn trong Main.java :(

các vấn đề có thể tạo ra các đối tượng danh sách
Kemal Duran

1
[kiếp sau] trong ứng dụng khởi động mùa xuân của tôi, @Access(AccessType.FIELD)(trong trường hợp của tôi, tôi muốn đi với FIELD) là người duy nhất mà giải quyết nó
Scaramouche

Câu trả lời:


168

Bạn đang sử dụng chiến lược truy cập trường (được xác định bởi chú thích @Id). Đặt bất kỳ chú thích liên quan đến JPA nào ngay trên mỗi trường thay vì thuộc tính getter

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

@Arthur Ronald FD Garcia: Cảm ơn, nó hoạt động rất tốt. Tuy nhiên, chương trình hiện đã bị dừng bởi một chương trình mới. object references an unsaved transient instance - save the transient instance before flushingBạn có biết về lỗi này. Nếu không cứ để đó. Tôi đang tìm kiếm.

@Arthur Ronald FD Garcia: Xin chào một lần nữa, tôi đã thấy giải pháp cho lỗi hiện tại của mình mà tôi đã hỏi trong nhận xét trước của mình. Đây là liên kết. stackoverflow.com/questions/1667177/… Giải pháp bao gồm cascade=CascadeType.ALL. Nhưng đối với tôi, nó hiển thị lỗi và không có đề xuất trong nhật thực của tôi. Bạn có biết gì về điều đó. :)

9
@Arthur +1 Bắt tốt @MaRaVan Bạn có thể sử dụng chiến lược truy cập trường hoặc chiến lược truy cập thuộc tính nhưng bạn phải nhất quán trong một hệ thống phân cấp lớp, bạn không thể kết hợp các chiến lược, ít nhất là không có trong JPA 1.0. Tuy nhiên, JPA 2.0 giúp bạn có thể kết hợp các chiến lược, nhưng bạn sẽ cần thêm chú thích (và do đó phức tạp hơn). Vì vậy, khuyến nghị là chọn một chiến lược và áp dụng chiến lược đó trong ứng dụng của bạn. Xem 2.2.2.2. Loại truy cập .
Pascal Thivent 22/09/10

@Arthur Ronald FD Garcia: Hmmmm ... Tôi đã thêm persistence.cascadeBây giờ nó đã được xóa. Nhưng tôi lại gặp lỗi cũ object references an unsaved transient instance - save the transient instance before flushingAnY Gợi ý !!! : + |

@All: Không ai nói với tôi về việc sai mã hoàn toàn trong Main.java :(

78

Thêm trường @ElementCollectionvào danh sách đã giải quyết được vấn đề này:

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

5
+ targetClasskhông cần thiết vì bạn đã đề cập đến loại danh sách<Integer>
O.Badr

1
Nó có vẻ là cần thiết, vì tôi đang tìm kiếm giải pháp cho chính xác vấn đề này và thêm @ElementCollection (targetClass = String.class) vào danh sách chuỗi đơn giản của tôi đã giải quyết được nó.
Angel O'Sphere,

32

Vấn đề với các chiến lược Access

Là một nhà cung cấp JPA, Hibernate có thể xem xét bên trong cả các thuộc tính thực thể (trường cá thể) hoặc các trình truy cập (thuộc tính cá thể). Theo mặc định, vị trí của @Idchú thích cung cấp chiến lược truy cập mặc định. Khi được đặt trên một trường, Hibernate sẽ đảm nhận quyền truy cập dựa trên trường. Được đặt trên getter nhận dạng, Hibernate sẽ sử dụng quyền truy cập dựa trên thuộc tính.

Truy cập dựa trên thực địa

Khi sử dụng quyền truy cập dựa trên trường, việc thêm các phương thức cấp thực thể khác linh hoạt hơn nhiều vì Hibernate sẽ không xem xét những phần đó của trạng thái tồn tại

@Entity
public class Simple {

@Id
private Integer id;

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

//getter +setter
}

Quyền truy cập dựa trên tài sản

Khi sử dụng quyền truy cập dựa trên thuộc tính, Hibernate sử dụng trình truy cập để đọc và ghi trạng thái thực thể

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

}

Nhưng bạn không thể sử dụng đồng thời cả quyền truy cập Dựa trên Trường và Dựa trên Thuộc tính. Nó sẽ hiển thị như vậy lỗi cho bạn

Đối với ý tưởng hơn theo này


9
@Access(AccessType.PROPERTY)
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="userId")
public User getUser() {
    return user;
}

Tôi có những vấn đề tương tự, tôi đã giải quyết nó bằng cách thêm @Access(AccessType.PROPERTY)


trong ứng dụng khởi động mùa xuân của tôi, @Access(AccessType.FIELD)(trong trường hợp của tôi, tôi muốn đi với FIELD) là người duy nhất mà giải quyết nó
Scaramouche

2

Đừng lo lắng! Sự cố này xảy ra do chú thích. Thay vì truy cập dựa trên Trường, truy cập dựa trên Thuộc tính giải quyết vấn đề này. Mã như sau:

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

Chỉ cần chèn chú thích @ElementCollection lên biến danh sách mảng của bạn, như bên dưới:

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

Tôi hi vọng cái này giúp được


Thật tuyệt! Nó làm việc như một say mê! Các câu trả lời khác không phù hợp với tôi. Điều này thực sự đã làm được. Câu trả lời chính khiến tôi gặp nhiều vấn đề hơn mà tôi phải giải quyết riêng với câu trả lời này. Câu trả lời tốt!
Trình biên dịch v2

2

Trong trường hợp của tôi, thật là ngu ngốc khi thiếu chú thích @OneToOne, tôi đã đặt @MapsId mà không có chú thích đó


1

Mặc dù tôi mới làm quen với chế độ ngủ đông nhưng với ít nghiên cứu (chúng tôi có thể thử và sai), tôi phát hiện ra rằng đó là do sự không thống nhất trong việc chú thích các phương thức / tệp.

khi bạn chú thích @ID trên biến, hãy đảm bảo rằng tất cả các chú thích khác cũng chỉ được thực hiện trên biến và khi bạn đang chú thích nó trên phương thức getter, hãy đảm bảo rằng bạn chỉ chú thích tất cả các phương thức getter khác chứ không phải các biến tương ứng của chúng.


1

Trong trường hợp bất kỳ ai khác đến đây với cùng một vấn đề mà tôi gặp phải. Tôi đã gặp lỗi tương tự như trên:

Không gọi được phương thức init; ngoại lệ lồng nhau là org.hibernate.MappingException: Không thể xác định loại cho: java.util.Collection, tại bảng:

Hibernate sử dụng phản xạ để xác định cột nào trong một thực thể. Tôi có một phương thức riêng bắt đầu bằng 'get' và trả về một đối tượng cũng là một thực thể ngủ đông. Ngay cả những getters riêng mà bạn muốn ngủ đông bỏ qua cũng phải được chú thích bằng @Transient. Sau khi tôi thêm chú thích @Transient, mọi thứ đều hoạt động.

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.