【发布时间】:2014-02-26 15:23:51
【问题描述】:
我最近将 Spring 2.5 升级到 3.2,将 Hibernate 3 升级到 4.2.8,以进行 Web 应用程序的一般升级。大多数事情现在都在工作,但是有一个 Criteria 事务不工作,让我感到困惑。新版本没有返回结果(但没有错误),而旧版本正确检索了请求的值。
新旧版本的代码是一样的,我已经验证到达它的参数是一样的。这是Java代码:
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ViewingResource.class);
criteria.createCriteria("viewings","currentViewings");
criteria.add(Property.forName("currentViewings.id").eq(viewingId));
ViewingResource result = (ViewingResource)criteria.uniqueResult();
ViewingResource 是我的实体,定义如下:
@Entity
@DiscriminatorValue("viewing")
public class ViewingResource extends AbstractInformationResource {
private static final long serialVersionUID = -4569093742552159052L;
@OneToOne(targetEntity = Attribute.class, fetch = FetchType.LAZY)
@JoinColumn
private Attribute primaryAttribute;
@OneToMany(targetEntity = Viewing.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval=true)
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@JoinTable(name = "informationresource_viewings")
@OrderBy("sort")
private Set<ResourceViewing> viewings;
public Set<ResourceViewing> getViewings() {
return viewings;
}
public Attribute getPrimaryAttribute() {
return primaryAttribute;
}
}
至于它所扩展的抽象类:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "type",
discriminatorType = DiscriminatorType.STRING
)
@Table(name = "informationresource")
abstract public class AbstractInformationResource extends PersistentEntity<String> {
private static final long serialVersionUID = 8709376067232042462L;
@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private int sort;
public String getId() {
return id;
}
public String getName() {
return name;
}
public int getSort() {
return sort;
}
}
原来的 PersistentEntity 只是 Serializable 的扩展,有一个 id 没有注释。
我启用了 Hibernate 日志,发现问题可能出在 Hibernate 3 和 4 之间的注释工作方式上,因为 Hibernate 生成的 SQL 字符串以这种方式不同:
休眠 3:
select
... (maps to all columns)
from
informationresource this_
inner join
informationresource_viewings viewings3_
on this_.id=viewings3_.informationresource_id
inner join
Viewing currentvie1_
on viewings3_.viewings_id=currentvie1_.id
where
this_.type in (
'viewing', 'directory'
)
and currentvie1_.id=?
而在 Hibernate 4 中,生成的 SQL 不执行连接:
select
... (maps to all columns, except type, attributeType and fieldName)
from
informationresource this_,
informationresource_viewings viewings3_,
Viewing currentvie1_
where
this_.id=viewings3_.informationresource_id
and viewings3_.viewings_id=currentvie1_.id
and this_.type='viewing'
and currentvie1_.id=?
有任何提示可以帮助我解决这个问题吗?我目前的猜测是,也许我跳过了一些自 Hibernate 3 以来已更改或修改的注释定义,但到目前为止,我在声明它们的方式中还没有发现任何非法的东西 - 我尝试修改 @Join 有到目前为止一直不成功。
编辑。在玩了一段时间之后,我发现这个问题可能与抽象类的@DiscriminatorColumn有关。我发现问题在于我对这种请求的类型从不是“查看”,而是“目录”。在旧生成的 SQL 中,我生成了两种类型:
this_.type in (
'viewing', 'directory'
)
但在新的 sql 中,这仅限于“查看”:
and this_.type='viewing'
我在新 SQL 中更改了这一行,它返回了我需要的正确值。列类型只有这两个值,“查看”和“目录”。所以我现在的问题是如何让 Criteria 继续询问那里的类型而不是强制“查看”类型。
【问题讨论】:
标签: java hibernate migration criteria