【问题标题】:OneToOne custom join queryOneToOne 自定义连接查询
【发布时间】:2012-03-13 00:13:26
【问题描述】:

我想对 OneToOne 关系进行自定义联接查询。我需要在 where 部分再添加一个子句,因为没有它我会得到 More than one row with the given identifier was found: com.example.Container_$$_javassist_0@17156065, for class: com.example.AnyContainer 是否可以这样做?

容器.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 的东西作为连接查询。而对于?像往常一样应该有所有者。我又添加了一个条件 -> 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 的东西作为连接查询。而对于?像往常一样应该有所有者。我又添加了一个条件 -> 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
}

编辑:在AnyContainer 中将ManyToOne -> 更新为OneToOne 我尝试使用在类OResourceObjectShadow 上注释的命名查询来使用@Loader,但它没有被使用。此外,我仅尝试在 AnyContainer 类上使用它作为测试,但根本没有使用。

如何为OResourceObjectShadow 中的OneToOne 关系处理自定义连接?有没有办法以编程方式(例如通过自定义 tuplizer 或类似的东西)?

【问题讨论】:

    标签: java hibernate join one-to-one


    【解决方案1】:

    当您想要基于多个列进行连接时,您可以在 HQL

    中使用 with 运算符
    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>
    

    此映射将始终基于两列连接表。

    阅读示例 here 或 API 文档 here

    【讨论】:

    • 我试图将@Formula("..some hql..") 添加到O.extension 映射,但它没有按我的意愿使用,AnyContainer 仍然只通过owner_oidowner_id 进行搜索,ownerType 是不曾用过。是否可以删除 @OneToOne 注释并以某种方式通过一些 Tuplizer 或类似的东西以编程方式映射这种关系?
    • 我找不到任何带有注释的示例,看看this是否有帮助。
    猜你喜欢
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 2010-09-25
    • 2020-11-28
    相关资源
    最近更新 更多