org.hibernate.MappingException : 다음에 대한 유형을 결정할 수 없습니다 : java.util.List, at table : College, for columns : [org.hibernate.mapping.Column (students)]


97

내 프로젝트의 모든 CRUD 작업에 Hibernate를 사용하고 있습니다. 일대 다 및 다 대일 관계에는 작동하지 않습니다. 아래 오류가 발생합니다.

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

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


}

콘솔:

 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의 완전한 코드 잘못된 배치에 대해 말하지 않았습니다. :(

문제는리스트 객체의 생성 할 수 있습니다
케말 듀란

1
[옛날 나중에] 나의 봄 부팅 응용 프로그램에서, @Access(AccessType.FIELD)(내 경우에는 내가 필드를 가고 싶어) 그것을 해결하는 유일한 하나
스카라무슈

답변:


175

필드 액세스 전략을 사용하고 있습니다 (@Id 주석으로 결정). getter 속성 대신 각 필드 바로 위에 JPA 관련 주석을 넣으십시오.

@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. 그러나 나를 위해 그것은 내 일식에 오류와 제안이 없습니다. 그것에 대해 아는 것이 있습니까? :)

10
@Arthur +1 Good catch @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의 완전한 코드를 잘못 배치에 대해 말해주지

79

@ElementCollection목록 필드에를 추가하면 이 문제가 해결되었습니다.

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

5
+ targetClass목록의 유형을 언급했듯이 필요하지 않습니다<Integer>
O.Badr

1
정확히이 문제에 대한 해결책을 찾고 있었고 @ElementCollection (targetClass = String.class)을 간단한 문자열 목록에 추가하여 해결했기 때문에 필요한 것 같습니다.
Angel O'Sphere

33

액세스 전략의 문제

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

}

그러나 필드 기반 및 속성 기반 액세스를 동시에 사용할 수는 없습니다. 그 오류처럼 표시됩니다.

더 아이디어에 따라


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)(내 경우에는 내가 필드를 가고 싶어) 그것을 해결하는 유일한 하나
스카라무슈

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

1

나는 최대 절전 모드에 익숙하지 않지만 약간의 연구 (시행 착오라고 말할 수 있음)가 방법 / 파일에 주석을다는 데있어 일관성이 없다는 것을 알았습니다.

변수에 @ID에 주석을 달 때 다른 모든 주석도 변수에서만 수행되는지 확인하고 getter 메소드에 주석을 추가 할 때 해당 변수가 아닌 다른 모든 getter 메소드에만 주석을 달아야합니다.


1

다른 사람이 내가 만난 것과 같은 문제로 여기에 착륙하는 경우. 위와 같은 오류가 발생했습니다.

init 메소드 호출에 실패했습니다. 중첩 된 예외는 org.hibernate.MappingException입니다 : 다음에 대한 유형을 결정할 수 없습니다 : java.util.Collection, 테이블 :

Hibernate는 반사를 사용하여 엔티티에있는 열을 결정합니다. 나는 'get'으로 시작하고 최대 절전 엔터티 인 개체를 반환하는 개인 메서드가 있습니다. 최대 절전 모드에서 무시하려는 개인 getter도 @Transient로 주석 처리해야합니다. @Transient 주석을 추가하면 모든 것이 작동했습니다.

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}

1

제 경우에는 @OneToOne 주석이 어리석게 누락되었습니다. 나는 그것없이 @MapsId를 설정했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.