2012-03-13 10 views
0

OneToOne関係のカスタム結合クエリが必要です。私はそれがなければ、More than one row with the given identifier was found: [email protected], for class: com.example.AnyContainerそれを行うことは可能ですので、私は部分に1つ以上の条項を追加する必要がありますか?OneToOneカスタム結合クエリ

Container.java

@Entity 
@Table(name = "container") 
@Inheritance(strategy = InheritanceType.JOINED) 
public abstract class Container implements Serializable { 

    private String oid; 
    private Long id; 

    @Id 
    @GeneratedValue(generator = "ContainerIdGenerator") 
    @GenericGenerator(name = "ContainerIdGenerator", strategy = "com.example.ContainerIdGenerator") 
    @Column(name = "id") 
    public Long getId() { 
     return id; 
    } 

    @Id 
    @GeneratedValue(generator = "OidGenerator") 
    @GenericGenerator(name = "OidGenerator", strategy = "com.example.OidGenerator") 
    @Column(unique = true, nullable = false, updatable = false, length = 36) 
    public String getOid() { 
     return oid; 
    } 
    ..other getters/setters 
} 

O.java:Hibernateはselect c.ownerType, c.owner_oid, c.owner_id from any c where c.owner_oid=? and c.owner_id=?クエリを使用しますが、ここで私は、クエリに参加するために、このfrom AnyContainer as c where c.owner = ? and c.ownerType = 0ようなものを使用します。そして?いつものようにオーナーがいるはずです。私は1つの以上の条件が追加 - >ownerType = 0

@Entity 
@Table(name = "object") 
@ForeignKey(name = "fk_container") 
public abstract class O extends Container { 

    private AnyContainer extension; 

    @OneToOne(optional = true, mappedBy = "owner") 
    @ForeignKey(name = "none") 
    @Cascade({org.hibernate.annotations.CascadeType.ALL}) 
    public AnyContainer getExtension() { 
     return extension; 
    } 
    ...other getters/setters 
} 

ResourceObjectShadow.java:Hibernateはselect c.ownerType, c.owner_oid, c.owner_id from any c where c.owner_oid=? and c.owner_id=?クエリを使用しますが、ここで私は、クエリへの参加などのために、このfrom AnyContainer as c where c.owner = ? and c.ownerType = 1ようなものを使用したいと思うでしょう。そして?いつものようにオーナーがいるはずです。私は追加が1つの以上の条件 - >ownerType = 1

@Entity 
@Table(name = "resource_shadow") 
@ForeignKey(name = "fk_resource_object_shadow") 
public class ResourceObjectShadow extends O { 

    private AnyContainer attributes; 

    @OneToOne(optional = true, mappedBy = "owner") 
    @Cascade({org.hibernate.annotations.CascadeType.ALL}) 
    public AnyContainer getAttributes() { 
     return attributes; 
    } 
    ...other getters/setters 
} 

@Entity 
@Table(name = "any") 
public class AnyContainer implements Serializable { 

    private RContainerType ownerType; 
    private Container owner; 

    @ForeignKey(name = "fk_reference_owner") 
    @MapsId("owner") 
    @OneToOne(fetch = FetchType.LAZY) 
    @PrimaryKeyJoinColumns({ 
      @PrimaryKeyJoinColumn(name = "owner_oid", referencedColumnName = "ownerOid"), 
      @PrimaryKeyJoinColumn(name = "owner_id", referencedColumnName = "id") 
    }) 
    public Container getOwner() { 
     return owner; 
    } 
    ..other getters/setters 
} 

RContainerType.java

public enum RContainerType { 
    O, RESOURCE_OBJECT_SHADOW 
} 

編集:ManyToOneを更新 - >私はクラスOに注釈を付け名前付きクエリでユーザー@LoaderしようとしたOneToOne AnyContainer中にとResourceObjectShadowですが、使用されませんでした。また、私はAnyContainerクラスでそれを使用するためのテストとしてのみ試みましたが、まったく使用されませんでした。

そのOneToOne関係のカスタム結合を処理する方法OResourceObjectShadowの関係は?プログラムで(例えば、カスタムのtuplizerなどで)行う方法はありますか?

答えて

0

したい複数の列に基づいて参加するあなたはwith演算子を使用することができますHQL

from AnyBean as a join a.b with b.type = 0 

あなたは、このようなマッピングを作成したい場合は、formulaタグを使用することができます。

<one-to-one name="one2oneSubRef" 
class="com.manu.hibernate.mappings.domain.RefOnlyAMain" property-ref="parentARef" 
      cascade="all" > 

<formula>'A'</formula> 

<formula>a_id</formula> 

</one-to-one> 

このマッピングは、常に2つの列に基づいてテーブルを結合します。

hereまたはAPIドキュメントhereを読んでください。

+0

私は 'O.extension'マッピングに' @Formula( ".. some hql ..") 'を追加しようとしましたが、' AnyContainer'は 'owner_oid'と' 'owner_id'、' ownerType'は使われませんでした。 @OneToOneアノテーションを削除して、何らかの形でこの関係をいくつかのTuplizerなどを使ってプログラムでマップすることはできますか? – viliam

+0

注釈付きのサンプルが見つかりませんでしたか。[this](http://stackoverflow.com/questions/2334676/hibernate-many-to-one-using-formula)が役立つかどうかを確認してください。 – ManuPK