【问题标题】:Hibernate upgrade from 3 to 4: Criteria transaction ceases to workHibernate 从 3 升级到 4:Criteria 事务停止工作
【发布时间】: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


    【解决方案1】:

    感谢我在 EDIT 块中指定的提示,我终于找到了解决方案。

    解决方案来自于在基类中建立一个公式:

    @DiscriminatorFormula("case when type in ('viewing','directory') then 1 else 2 end")
    

    然后在查看资源中更改判别器值注释:

    @DiscriminatorValue("1")
    

    我真的不知道为什么在 Hibernate 3 中我得到了判别中的所有值,而在 Hibernate 4 中,值只有这个,因为代码根本没有改变。所以如果以后有人看到一些类似的行为,也许这个技巧可以帮助你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 2017-05-27
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 2012-08-10
      • 1970-01-01
      相关资源
      最近更新 更多