Hibernate复合键嵌套对象标准缺少条款

时间:2016-01-20 20:06:39

标签: hibernate hibernate-criteria composite-primary-key

目前我正在尝试使用hibernate(版本4.3.Final)来检索包含另一个hibernate bean关联的复合主键的对象。我使用的标准如下:

session.createCriteria(IdentityIdentifierHibernateBean.class)
       .setFetchMode("key.type", FetchMode.JOIN);   
       .createAlias("key.type","typeAlias",JoinType.INNER_JOIN);
       .add(Restrictions.and(
                Restrictions.eq("key.value", "value"),
                Restrictions.eq("typeAlias.id", "id value")))
       .list();

当我运行时,我收到错误:

1. SQL Error: 0, SQLState: 42P01
2. missing FROM-clause entry for table "typealias1_"

当我查看生成的sql时,原因显而易见,如下所示:

select 
     this_.type as type4_4_0_, 
     this_.value as value1_4_0_, 
     this_.id as id2_4_0_, this_.scope as scope3_4_0_ 
from 
     identityIdentifier this_ 
where 
    (this_.value=? and typealias1_.id=?)

当运行createAlias(或createCritera)时,hibernate是否要生成连接语句?我尝试了两种方法,并尝试为复合主键创建别名。无论哪种方式,这些方法都不起作用,因为从不创建连接语句。这是解决嵌入式复合主键中引用的嵌套hibernate bean的错误吗?或者我错过了什么......

这里参考hibernate类的简化版本(hashCode,equals和setters不包括在内):

@Entity
@Table(name = "identityIdentifier")
public class IdentityIdentifierHibernateBean implements Serializable {  
    private IdentityIdentifierPrimaryKey key;

    @EmbeddedId
    public IdentityIdentifierPrimaryKey getKey() {
        return key;
    }
}

@Embeddable
public class IdentityIdentifierPrimaryKey implements Serializable {
    private String value;
    private IdentityIdentifierTypeHibernateBean type;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "type", referencedColumnName="id",  unique = true, nullable = false)
    public IdentityIdentifierTypeHibernateBean getType() {
        return type;
    }

    @Column(name = "value", unique = false, nullable = false, length = 255)
    public String getValue() {
        return value;
    }
}

@Entity
@Table(name = "identityIdentifierType")
public class IdentityIdentifierTypeHibernateBean implements Serializable {
    private String id;

    @Id
    @Column(name = "id", unique = true, nullable = false, length=38)
    public String getId() {
        return id;
    }
}

2 个答案:

答案 0 :(得分:0)

在尝试使标准API工作无数个小时之后(我真的认为此时复合键已被破坏)我决定转而使用HQL查询。大约20分钟后,我很容易得到一个有效的查询。明智的话,不要使用复合键和标准api的组合。

Query query=session.createQuery(
            "select distinct identity from IdentityIdentifierHibernateBean as identity "
            + "inner join identity.key.type as type "
            + "where (identity.key.value=:value and type.id=:typeid)")
            .setParameter("value", type.getIdentityIdentifierValue())
            .setParameter("typeid", type.getTypeOfIdentityIdentifier());

beanList = (List<IdentityIdentifierHibernateBean>) query.list();

答案 1 :(得分:0)

我遇到了和你一样的问题,经过大量搜索后能够通过重构复合id来解决它。我已从复合ID中删除了hibernate实体,并将它们移动到实体本身。使用@MapsId(JPA 2.0)注释和@AttributeOverride实体表的键来映射外键。

http://www.objectdb.com/api/java/jpa/MapsId
http://www.objectdb.com/api/java/jpa/AttributeOverride