Пользовательский запрос на соединение OneToOne

Я хочу иметь настраиваемый запрос на соединение для отношений OneToOne. Мне нужно добавить еще одно предложение к where part, потому что без него я получаю 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
}

RContainerType.java

public enum RContainerType {   
    O, RESOURCE_OBJECT_SHADOW
}

Изменить: обновлено ManyToOne -> до OneToOne в AnyContainer. Я пытался использовать @Loader с именованным запросом, аннотированным для класса O и ResourceObjectShadow, но он не использовался. Также я пробовал только в качестве теста использовать его на AnyContainer классе, но не использовался вообще.

Как обрабатывать настраиваемое соединение для этого OneToOne отношения в O и ResourceObjectShadow? Есть ли способ сделать это программно (например, через настраиваемый туплайзер или что-то в этом роде)?


person viliam    schedule 13.03.2012    source источник


Ответы (1)


Если вы хотите объединить на основе нескольких столбцов, вы можете использовать оператор 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>

Это сопоставление всегда будет присоединяться к таблице на основе двух столбцов.

Прочтите пример здесь или в документации API здесь.

person ManuPK    schedule 13.03.2012
comment
Я попытался добавить @Formula("..some hql..") в O.extension сопоставление, но оно не использовалось так, как я хотел, AnyContainer по-прежнему искался только через owner_oid и owner_id, ownerType не использовался. Можно ли удалить аннотацию @OneToOne и каким-то образом эту связь отобразить программно через какой-нибудь Tuplizer или что-то в этом роде? - person viliam; 13.03.2012
comment
Я не смог найти никаких примеров с аннотацией, посмотрите, помогает ли это. - person ManuPK; 13.03.2012