org.hibernate.MappingException:タイプを判別できませんでした:java.util.List、テーブル:College、列:[org.hibernate.mapping.Column(students)]


96

プロジェクトのすべてのCRUD操作にHibernateを使用しています。1対多および多対1の関係では機能しません。それは私に以下のエラーを与えます。

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の完全なコードの誤配置:(

問題はリストオブジェクトの作成である可能性があります
Kemal Duran

1
[数十年後]私のスプリングブートアプリでは@Access(AccessType.FIELD)(私の場合、FIELDにしたかった)だけがそれを解決しました
Scaramouche

回答:


169

フィールドアクセス戦略を使用しています(@Idアノテーションによって決定されます)。ゲッタープロパティの代わりに各フィールドの真上に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です。しかし、私にとってはそれはエラーを示し、私の日食の提案はありません。それについて何か知っていますか。:)

9
@Arthur +1良いキャッチ@MaRaVanフィールドアクセス戦略またはプロパティアクセス戦略のいずれかを使用できますが、クラス階層内で一貫している必要があります。少なくともJPA 1.0では、戦略を混在させることはできません。JPA 2.0では、戦略を組み合わせることができますが、追加の注釈が必要になります(したがって、より複雑になります)。したがって、推奨事項は、1つの戦略を選択し、それをアプリケーションに固執することです。2.2.2.2を参照してくださいアクセスタイプ
Pascal Thivent、2010

@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は識別子ゲッターに配置され、プロパティベースのアクセスを使用します。

フィールドベースのアクセス

フィールドベースのアクセスを使用する場合、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に注釈を付けるときは、他のすべての注釈も変数のみに行われるようにし、ゲッターメソッドに同じように注釈を付けるときは、他のすべてのゲッターメソッドだけに注釈を付け、それぞれの変数には注釈を付けないようにしてください。


1

他の誰かが私が遭遇した同じ問題でここに着いた場合。上記と同じエラーが発生しました:

initメソッドの呼び出しに失敗しました。ネストされた例外はorg.hibernate.MappingException:次のタイプを判別できませんでした:java.util.Collection、テーブル:

Hibernateはリフレクションを使用して、エンティティにある列を決定します。「get」で始まり、休止状態のエンティティでもあるオブジェクトを返すプライベートメソッドがありました。hibernateに無視させたいプライベートゲッターでさえ、@ Transientで注釈を付ける必要があります。@Transientアノテーションを追加すると、すべてが機能しました。

@Transient 
private List<AHibernateEntity> getHibernateEntities() {
   ....
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.