在union-subclass映射中,子类如何声明所需的依赖项?

时间:2013-12-06 08:38:50

标签: hibernate hibernate-mapping

我很尴尬地将@ManyToOne(optional=false)实体映射添加到一个类,该类是参与union-subclass映射的子类。设置看起来像这样:

@Entity
public class Person {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "person")
    private Set<Role> roles;
}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Role {
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen")
    @SequenceGenerator(name = "gen", sequenceName = "id_seq", 
            initialValue =  1, allocationSize = 1)
    protected Long id;

    @ManyToOne(optional = false, cascade = { CascadeType.PERSIST, 
         CascadeType.REFRESH, CascadeType.MERGE })
    protected Person person;
}

@Entity
public class A extends Role {
    @ManyToOne(optional = false)
    private Status status = Status.INIT;
}

@Entity
public class B extends Role {
    String login;
}

这种方法适用于我迄今为止使用过的所有目的。现在,我正在修改一个分离的Person,它也有B角色(以前一起获取)并尝试通过以下方式保留更改:

entityManager.merge(person);

该行执行了一系列select语句来重新加载实体图,包括一个如下所示:

select role0_.id, role0_.person_id, role0_.login, role0_.status_id,
    person1_.id,
    status2_.id, status2_.code, status2_.visible
from
    (select id, person_id, login, null::int8 as status_id, 1 as clazz_
        from public.A
    union all select id, person_id, null::varchar as login, status_id, 2 as clazz_
        from public.B) role0_
inner join public.Person person1_ on role0_.person_id = person1_.id
inner join public.Status status2_ on role0_.status_id = status2_.id
where role0_.id=?

在此声明之后我得到了一个例外:

  

javax.persistence.EntityNotFoundException:无法找到id为2的my.company.Role

stacktrace的一部分:

Caused by: javax.persistence.EntityNotFoundException: Unable to find my.company.Role with id 2
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:181) [hibernate-entitymanager-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:263) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1025) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:952) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:681) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.type.EntityType.resolve(EntityType.java:499) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.type.EntityType.replace(EntityType.java:354) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:518) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.type.CollectionType.replace(CollectionType.java:661) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.type.TypeHelper.replace(TypeHelper.java:177) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:374) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:311) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]
        at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:153) [hibernate-core-4.3.0.CR1.jar:4.3.0.CR1]

问题是Role.id = 2的实体属于B类,因此没有status_id,因此不存在于选择结果集中。

我的问题很简单:Hibernate / JPA不支持如上所述的必需属性,如果是,我可以做些什么来记录和强制执行此依赖项的“非null”?

0 个答案:

没有答案