Hibernate使用null会话返回延迟加载的集合

时间:2012-07-18 17:01:52

标签: spring hibernate jpa-2.0

(已解决,见下文)

Hibernate 4.1 / Spring / JPA项目。我正在使用Spring& JPA注释用于事务支持,实体管理器注入等。

我在同一个事务中看到我的@OneToMany延迟加载的集合没有设置会话属性,当然也无法加载。如果我'left join fetch'强制加载,我会得到多条指向同一PersistentBag的记录 - 显然这会抛出'shared collection'异常。

这是我的设置:

交易实体('交易'的意思是在金融交易中)

代码:

@Entity
@Table(name = "transactionData")
@Access(AccessType.PROPERTY)
public class TransactionData extends AbstractTransaction implements java.io.Serializable {

   @Id
   @GeneratedValue(strategy = IDENTITY)
   @Column(name = "id", unique = true, nullable = false)
   public int getId() {
      return this.id;
   }

   public void setId(int id) {
      this.id = id;
   }

   @OneToMany(cascade=CascadeType.ALL,targetEntity=Location.class,fetch=FetchType.LAZY)
   @JoinColumns(
         {
            @JoinColumn(name="routecode",referencedColumnName="v_OPERSTAT"),
            @JoinColumn(name="cogrp", referencedColumnName="v_COUNTRY")      
         })
   @Transactional
   public Collection<Location> getLocations() {
      return super.getLocations();
   }

   public void setLocations(Collection<Location> l) {
      super.setLocations(l);
   }

}

交易的基类:

代码:

public abstract class AbstractTransaction  {

   private List<Location> _locations;

   @Override
   @Transactional
   public List<Location> getLocations() {
      return _locations;
   }

   @Override
   public void setLocations(List<Location> value) {
      _locations = value;
   }
}

交易实体使用2个整数类型列链接到Location实体,这些cols在Transaction或Location实体上都不是PK。

位置实体:

代码:

@Entity
@Table(name = "locations", uniqueConstraints = @UniqueConstraint(columnNames = {
      "cogrp", "cugrp", "bogrp", "status", "id" }))
public class Location implements java.io.Serializable {

   @Id
   @GeneratedValue(strategy = IDENTITY)
   @Column(name = "id", unique = true, nullable = false)
   public Integer getId() {
      return this.id;
   }

   public void setId(Integer id) {
      this.id = id;
   }

   @Column(name = "cogrp", nullable = false)
   public int getCogrp() {
      return this.cogrp;
   }

   public void setCogrp(int cogrp) {
      this.cogrp = cogrp;
   }

   @Column(name = "routecode")
   public Integer getRoutecode() {
      return this.routecode;
   }

   public void setRoutecode(Integer routecode) {
      this.routecode = routecode;
   }

}

交易实体与地点之间存在一对多关系,大多数交易实体将指向相同的地点列表。

现在,如果我执行以下查询:

代码:

select distinct t from " + Transaction.class.getName() + " t left join fetch t.locations where " + filterSQL

我得到了结果,但几乎每个Transaction实体都指向相同的PersistentBag位置 - 不用说这会导致共享引用错误。

如果我省略左连接提取,则所有实体都会返回延迟加载的集合,但没有设置会话属性。

如果我急切加载,我只会急切地加载2个实体,其余的仍然是懒惰的(我知道这是一个内置的限制,任何方式来覆盖它?)

修改 我开始相信这是Hibernate中的一个错误。如果你的查询返回指向同一集合的多个记录(我可能会添加完全有效的场景!),那么Hibernate将在急切地获取时重用相同的集合,并在延迟加载时将session设置为null。它将始终导致对同一集合的共享引用或“无会话”错误。

我已经切换到EclipseLink 2.4,在修复我的JPSQL之后,它似乎在上述情况下工作正常。

0 个答案:

没有答案