Hibernate 4.1/Spring/JPA project. I'm using Spring & JPA annotations for transactions support, entity manager injection etc.
What I'm seeing that within the same transaction my @OneToMany lazy-loaded collections dont have session property set, and of course cannot be loaded. If I do 'left join fetch' to force loading I get multiple records that point to the same PersistentBag - obviously this throws 'shared collection' exception.
Here is my setup:
Transaction entity ('transaction' is meant as in financial transaction)
Code:
@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);
}
}
Base class for Transaction:
Code:
public abstract class AbstractMTOTransaction implements IMTOTransaction {
private List<Location> _locations;
@Override
@Transactional
public List<Location> getLocations() {
return _locations;
}
@Override
public void setLocations(List<Location> value) {
_locations = value;
}
}
Transaction entity is linked to Location entity using 2 integer type columns, these cols are not PK on either Transaction or Location entity.
Location entity:
Code:
@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;
}
}
Transaction entity has 1-to-many relationship to locations, and most Transaction entities will point to the same list of locations.
Now, if I do the following query:
Code:
select distinct t from " + Transaction.class.getName() + " t left join fetch t.locations where " + filterSQL
I get results back, but almost every Transaction entity points to the same PersistentBag of locations - needless to say this causes shared references error.
If I omit left join fetch all entities come back with lazily loaded collections, but none have session property set.
If I do eager loading I only get 2 entities eagerly loaded, the rest are still lazy (I know this is a built-in restriction, any way to override that?)
Am I doing something completely wrong or this is a bug in Hibernate?
Peter