I tried to illumenate this with an example:
PrimitiveCollectionParent.java
Code:
package org.hibernate.test.annotations.collectionelement.cascade;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Formula;
@Entity(access=AccessType.FIELD)
public class PrimitiveCollectionParent {
@Id(generate= GeneratorType.AUTO)
private Integer Id;
@OneToMany(cascade=CascadeType.ALL)
private List<Double> scores = new ArrayList<Double>();
@Formula(value="(select sum(s.elt) from PrimitiveCollectionParent_scores s where s.PrimitiveCollectionParent_Id=id)")
private Double totalScore;
public void addScore (double score) {
scores.add(score);
}
public Double getTotalScore() {
return totalScore;
}
}
EntityCollectionParent.java
Code:
package org.hibernate.test.annotations.collectionelement.cascade;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Formula;
@Entity(access=AccessType.FIELD)
public class EntityCollectionParent {
@Id(generate= GeneratorType.AUTO)
private Integer Id;
@OneToMany(cascade=CascadeType.ALL,mappedBy="parent")
private List<Score> scores = new ArrayList<Score>();
@Formula(value="(select sum(s.score) from Score s where s.parent_Id=id)")
private Double totalScore;
public void addScore (double score) {
scores.add(new Score(this, score));
}
public Double getTotalScore() {
return totalScore;
}
}
Score.java
Code:
package org.hibernate.test.annotations.collectionelement.cascade;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity(access=AccessType.FIELD)
class Score {
@Id(generate=GeneratorType.AUTO)
private Integer id;
@ManyToOne
private EntityCollectionParent parent;
private double score;
public Score(EntityCollectionParent parent, double score) {
this.parent = parent;
this.score = score;
}
}
PrimitiveCollectionCascadeTest.java
Code:
package org.hibernate.test.annotations.collectionelement.cascade;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.test.annotations.TestCase;
public class PrimitiveCollectionCascadeTest extends TestCase {
@Override
protected Class[] getMappings() {
return new Class[]{PrimitiveCollectionParent.class,EntityCollectionParent.class,Score.class};
}
public final void testWithoutFlush () {
PrimitiveCollectionParent parent = new PrimitiveCollectionParent();
parent.addScore(13.0);
parent.addScore(24.5);
Session s = openSession();
Serializable id = s.save(parent);
s.close();
s = openSession();
PrimitiveCollectionParent persisted = (PrimitiveCollectionParent) s.get(PrimitiveCollectionParent.class,id);
s.close();
assertEquals(37.5,persisted.getTotalScore());
}
public final void testWithFlush () {
PrimitiveCollectionParent parent = new PrimitiveCollectionParent();
parent.addScore(13.0);
parent.addScore(24.5);
Session s = openSession();
Serializable id = s.save(parent);
s.flush();
s.close();
s = openSession();
PrimitiveCollectionParent persisted = (PrimitiveCollectionParent) s.get(PrimitiveCollectionParent.class,id);
s.close();
assertEquals(37.5,persisted.getTotalScore());
}
public final void testWithEntities () {
EntityCollectionParent parent = new EntityCollectionParent();
parent.addScore(13.0);
parent.addScore(24.5);
Session s = openSession();
Serializable id = s.save(parent);
s.close();
s = openSession();
EntityCollectionParent persisted = (EntityCollectionParent) s.get(EntityCollectionParent.class,id);
s.close();
assertEquals(37.5,persisted.getTotalScore());
}
}
As you can see the test works perfectly well when flushing or using a collection of entities. Is this due to the mappedBy property of the collection of entities? If so, I cannot specify "mappedBy"on a collection of primitives (obviously, since the primitive type will not hold a reference to the parent).