OneToOne自定义联接查询



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

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的查询作为联接查询。为了什么?应该像往常一样有主人。我又增加了一个条件->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
}

R容器类型.java

public enum RContainerType {   
    O, RESOURCE_OBJECT_SHADOW
}

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

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

当您想要基于多列的联接时,可以在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>

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

请阅读此处的示例或此处的API文档。

最新更新