0

Hibernate 3.6.10ベースのJPA2.0を使用しており、多対多の関係にある2つのオブジェクトを作成しました。

@Entity
@Table(name="Project")
public class Project implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String topic;
    @Lob
    @Basic(fetch=FetchType.LAZY)
    private String content;
    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="TrProj_Area",joinColumns=@JoinColumn(name="TrProj_ID"), inverseJoinColumns=@JoinColumn(name="Area_ID"))
    private Set<Area> areas = new HashSet<Area>();
    //getters and setters
}

@Entity
@Table(name="Area")
public class Area implements Serializable{
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Integer id;
     private String name;
     @ManyToMany(mappedBy="areas")
     private Set<Project> projects;
     //getters and setters
}

Projectエンティティにはcontentプロパティがあります。これは、Lob and Lazy Fetchです。次のようなクエリを作成したとき、次のようになります。

select distinct o from Project o join o.areas a where a.id in(?,?)

MySQL 5.5では正常に動作しますが、SQLServer2005では動作しません。SQLServerエラーログは次のとおりです。

Error code 306, SQL state S0001: The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator

この問題はcontentプロパティが原因であることがわかっています。遅延フェッチ構成が機能しないようです。テキスト列をselectdistinctステートメントに含めることはできませんが、エンティティから削除できません。どうすれば解決できますか?この問題?


20120722に追加

MySQL(ドライバーとしてmysql-connector-java-5.1.10-bin.jar)が休止状態でSQLを生成したトレースを以下に示します。

Hibernate: 
select
    distinct proj0_.id as id1_,
    proj0_.content as content1_,
    proj0_.topic as topic1_,
  from
    Project proj0_ 
inner join
    Proj_Area areas1_ 
        on proj0_.id=areas1_.Proj_ID 
inner join
    Area area2_ 
        on areas1_.Area_ID=area2_.id 
where
    area2_.id in (
            ? , ?
        )
order by
    proj0_.id desc limit ?

これはSQLServer2005(ドライバーとしてsqljdbc4.jar)によって生成されます。エラーはgroupbyステートメントが原因で発生するのではないかと心配しています

Hibernate: 
    WITH query AS (select
        ROW_NUMBER() OVER (
    order by
       proj0_.id desc) as __hibernate_row_nr__,
       proj0_.id as id1_,
       proj0_.content as content1_,
       proj0_.topic as topic1_,
    from
       project proj0_ 
    inner join
       proj_area areas1_ 
           on proj0_.id=areas1_.proj_id 
    inner join
       area area2_ 
           on areas1_.area_id=area2_.id 
    where
       area2_.id in (? , ?)) 
    group by
        proj0_.id,
        proj0_.content,
        proj0_.topic) SELECT
        * 
    FROM
        query 
    WHERE
        __hibernate_row_nr__ BETWEEN ? AND ?
4

2 に答える 2

2

回避策は、サブクエリを使用してID値の個別のセットを選択し、それを使用して返される値を制限することです。id以外にdistinctを適用する必要がないため、これは機能します。

SELECT b 
FROM Project b 
WHERE b.id IN(SELECT distinct o.id 
              FROM Project o join o.areas a 
              WHERE a.id IN(?,?))
于 2012-07-21T16:42:24.003 に答える
0

JB Nizetが言うように、 http: //docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#performance-fetching-lazypropertiesを参照してください。これは、lazypropertiesのフェッチ機能が機能しないためです。ドキュメントによると、2つの解決策があります。最後に、ドキュメントに書かれているように、好ましいソリューションを選択します。

少なくとも読み取り専用トランザクションの場合、不要な列読み取りを回避する別の方法は、HQLまたはCriteriaクエリのプロジェクション機能を使用することです。これにより、ビルド時のバイトコード処理が不要になり、確かに推奨されるソリューションです。

もう少し説明があります。@Basic(fetch = FetchType.LAZY)が機能しませんか?

于 2012-07-22T09:47:06.463 に答える