Hibernate 复合键嵌套对象条件从子句中丢失
Hibernate Composite Key Nested Object Criteria Missing From Clause
目前我正在尝试使用 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=?)
当 运行ning createAlias(或 createCritera)不是 hibernate 时,假设生成连接语句?我已经尝试了这两种方法并尝试为复合主键创建别名。无论哪种方式,这些方法都不会像永远不会创建连接语句一样起作用。这是解决嵌入式复合主键中引用的嵌套休眠 bean 的错误吗?或者我错过了什么....
作为参考,这里有一个简化版本的 hibernate 类(不包括 hashCode、equals 和 setter):
@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;
}
}
经过无数小时的尝试使条件 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();
我 运行 遇到了和你一样的问题,经过大量搜索后,我通过重构复合 ID 解决了这个问题。我已经从复合 id 中删除了休眠实体并将它们移动到实体本身。外键是使用 @MapsId(JPA 2.0) 注释和实体键 table 由 @AttributeOverride 映射的。
http://www.objectdb.com/api/java/jpa/MapsId
http://www.objectdb.com/api/java/jpa/AttributeOverride
目前我正在尝试使用 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=?)
当 运行ning createAlias(或 createCritera)不是 hibernate 时,假设生成连接语句?我已经尝试了这两种方法并尝试为复合主键创建别名。无论哪种方式,这些方法都不会像永远不会创建连接语句一样起作用。这是解决嵌入式复合主键中引用的嵌套休眠 bean 的错误吗?或者我错过了什么....
作为参考,这里有一个简化版本的 hibernate 类(不包括 hashCode、equals 和 setter):
@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;
}
}
经过无数小时的尝试使条件 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();
我 运行 遇到了和你一样的问题,经过大量搜索后,我通过重构复合 ID 解决了这个问题。我已经从复合 id 中删除了休眠实体并将它们移动到实体本身。外键是使用 @MapsId(JPA 2.0) 注释和实体键 table 由 @AttributeOverride 映射的。
http://www.objectdb.com/api/java/jpa/MapsId
http://www.objectdb.com/api/java/jpa/AttributeOverride