2

JPA (Hibernate) を使用していますが、データベースからオブジェクトを取得しようとすると問題が発生します。Glassfish 3.1.2、Hibernate、および Oracle データベース 10.2.0.4 を使用しています。

私のアプリケーションのコンセプトは次のとおりです。

回答はフォームへの回答です。フォームはカテゴリに属します。ユーザーはフォームを作成できます。ユーザーは答えることができます。

そう:

  • 1 つのフォームには 1 つのカテゴリがあるため、1 つのカテゴリに複数のフォームが含まれる場合があります。
  • 1 つの回答には 1 つのフォームがあり、1 つのフォームには複数の回答がある場合があります
  • 1 つの回答には 1 人のユーザー (回答の作成者) がいます
  • 1 つのフォームには 1 人のユーザー (フォームの作成者) がいます

答えを取得しようとするとエラーが発生します (投稿の下部を参照) が、奇妙なのは次の事実です。

  • データベースに回答がない場合。動作します(少なくともエラーはスローされません)

  • answer.form_id 列に値のない回答がデータベースに存在する場合。動作します(少なくともエラーはスローされません)

  • フォーム属性を削除し、回答クラスからユーザー属性を許可すると; できます!回答はデータベースから取得され、ユーザーもフェッチされます。

  • ユーザー属性を削除し、フォーム属性を回答クラスから削除すると、それは失敗します!回答はデータベースから取得されません。(この投稿の最後にエラーを投げます)

  • フォームクラスからカテゴリとユーザー属性を削除すると、できます!回答はデータベースから取得され、ユーザーとフォームも取得されます! しかし、私はそれをこのようにすることはできません。フォーム エンティティにカテゴリとユーザーが必要です。

  • カテゴリ属性またはユーザー属性のいずれかを削除して、もう一方をフォーム クラスに入れると、それは失敗します。

休止状態は、他のエンティティよりも先にフェッチできないようです:

  • 回答 > ユーザー : OK
  • 回答 > カテゴリまたはユーザーのないフォーム: OK
  • フォーム > カテゴリ: OK
  • フォーム > ユーザー: OK
  • 回答 > フォーム > カテゴリ: FAIL
  • 回答 > フォーム > ユーザー: FAIL

ただし<property name="hibernate.max_fetch_depth" value="3"/>、persistence.xml に設定しました。

問題のアイデアや提案はありますか? フォームエンティティ、その属性カテゴリ、またはユーザーのいずれかのようです。

ありがとう


これが私の実際のコードです。わかりやすくするために大幅に縮小されています。

フォーム クラス:

@Entity
@Table(name="FORM")
public class Form implements Serializable {

    private static final long serialVersionUID = -2101681231828548611L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "G_FORM")
    @SequenceGenerator(name = "G_FORM", sequenceName = "FORM_ID_SEQ")
    @Column(name = "ID", unique = true, nullable = false)
    private int id;

    private String name;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn
    private Category category;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn
    private User user;

    //more fields and usual getters and setters
}

ユーザークラス:

@Entity
@Table(name = "USERS")
public class User implements Serializable {

    private static final long serialVersionUID = -821421797110076396L;

    @Id
    @Column(name = "ID")
    private String id;

    @NotNull
    @Column
    private String email;

    @NotNull
    private String password;

    @Column(name="PARENT_ID")
    private User parent;

    //more fields and usual getters and setters
}

回答クラス:

@Entity
public class Answer implements Serializable {

    private static final long serialVersionUID = -8514559401482729639L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "G_ANSWER")
    @SequenceGenerator(name = "G_ANSWER", sequenceName = "ANSWER_ID_SEQ")
    @Column(name = "ID", unique = true, nullable = false)
    private int id;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn
    private Form form;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn
    private User user;

    //more fields and usual getters and setters
}

失敗する AnswerDAO メソッド:

public List<Answer> getAllAnswers() throws Exception{
    TypedQuery<Answer> query = em.createQuery( "SELECT a FROM Answer a ORDER BY a.id", Answer.class );
    return query.getResultList();
    //return em.createQuery("SELECT a FROM Answer a", Answer.class).getResultList();
}

私のpersistence.xmlでは:

<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.max_fetch_depth" value="3"/>  

休止状態によって生成された sql (正しいようですか?):

Infos: Hibernate: select answer0_.ID as ID1_0_, answer0_.ANSWER_XML as ANSWER2_0_, answer0_.DATE_UPLOAD as DATE3_0_, answer0_.form_ID as form4_0_, answer0_.user_ID as user5_0_ from Answer answer0_ order by answer0_.ID
Infos: Hibernate: select form0_.ID as ID1_2_2_, form0_.category_NAME as category6_2_2_, form0_.DATE_UPLOAD as DATE2_2_2_, form0_.extention as extentio3_2_2_, form0_.name as name4_2_2_, form0_.QUESTION_XML as QUESTION5_2_2_, form0_.user_ID as user7_2_2_, category1_.NAME as NAME1_1_0_, category1_.DATE_CREATION as DATE2_1_0_, user2_.ID as ID1_5_1_, user2_.ANSWER_COUNT as ANSWER2_5_1_, user2_.DATE_INSCRIPTION as DATE3_5_1_, user2_.DATE_LAST_ANSWER as DATE4_5_1_, user2_.DATE_LAST_LOGIN as DATE5_5_1_, user2_.email as email6_5_1_, user2_.firstname as firstnam7_5_1_, user2_.FORM_COUNT as FORM8_5_1_, user2_.lastname as lastname9_5_1_, user2_.PARENT_ID as PARENT10_5_1_, user2_.password as passwor11_5_1_ from FORM form0_ left outer join Category category1_ on form0_.category_NAME=category1_.NAME left outer join USERS user2_ on form0_.user_ID=user2_.ID where form0_.ID=?

Eclipse コンソールのエラーも大幅に減少しました。

WARN: SQL Error: 17027, SQLState: null
ERROR: Le flux de données est déjà fermé
Infos: HHH000327: Error performing load command : org.hibernate.exception.GenericJDBCException: could not load an entity: [be.adehis.bean.Form#96]
Avertissement: EJB5184:A system exception occurred during an invocation on EJB AnswerDAO, method: public java.util.List be.adehis.database.dao.AnswerDAO.getAllAnswers() throws java.lang.Exception
Avertissement: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    at ...
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not load an entity: [be.adehis.bean.Form#96]
    at ... 
Caused by: org.hibernate.exception.GenericJDBCException: could not load an entity: [be.adehis.bean.Form#96]
    at ...
Caused by: java.sql.SQLException: Le flux de données est déjà fermé
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)

Avertissement: EJB5184:A system exception occurred during an invocation on EJB AnswerService, method: public java.util.List be.adehis.service.answer.AnswerService.getAllAnswers() throws java.lang.Exception
Avertissement: javax.ejb.EJBTransactionRolledbackException
    at ...
Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    at ...
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not load an entity: [be.adehis.bean.Form#96]
    at ...
Caused by: org.hibernate.exception.GenericJDBCException: could not load an entity: [be.adehis.bean.Form#96]
    at ...
Caused by: java.sql.SQLException: Le flux de données est déjà fermé
4

3 に答える 3