Skip to content

Commit

Permalink
[#1566] Update to hibernate 4.2.15
Browse files Browse the repository at this point in the history
[#1566] Partial Fix TransientObjectException when orphanRemoval = true and removing and adding items
[#1503] Partial fix Nested OneToMany relationships with orphanRemoval fails to commit
[#1847] Partial fix Orphan removal not cascaded for @OnetoOne relationships
  • Loading branch information
xael-fry committed Jul 31, 2014
1 parent 46bfbfb commit 6011111
Show file tree
Hide file tree
Showing 19 changed files with 324 additions and 188 deletions.
8 changes: 4 additions & 4 deletions framework/dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ require: &allDependencies
- org.bouncycastle -> bcprov-jdk15 1.45
- org.codehaus.groovy -> groovy-all 2.3.1
- org.eclipse.jdt.core 3.10.0.v20140604-1726
- org.hibernate -> hibernate-core 4.1.3.Final
- org.hibernate -> hibernate-commons-annotations 4.0.1.Final
- org.hibernate -> hibernate-entitymanager 4.1.3.Final
- org.hibernate -> hibernate-core 4.2.15.Final
- org.hibernate -> hibernate-commons-annotations 4.0.2.Final
- org.hibernate -> hibernate-entitymanager 4.2.15.Final
- org.hibernate -> hibernate-validator 4.1.0.Final
- org.hibernate -> jboss-logging 3.1.0.GA
- org.hibernate -> jboss-transaction-api_1.1_spec 1.0.0.Final
- org.hibernate -> jboss-transaction-api_1.1_spec 1.0.1.Final
- org.hibernate.javax.persistence -> hibernate-jpa-2.0-api 1.0.1.Final
- org.javassist -> javassist 3.18.2-GA
- org.jboss.netty -> netty 3.9.2.Final
Expand Down
Binary file not shown.
1 change: 0 additions & 1 deletion framework/lib/hibernate-core-4.1.3.Final.docurl

This file was deleted.

Binary file removed framework/lib/hibernate-core-4.1.3.Final.jar
Binary file not shown.
Binary file added framework/lib/hibernate-core-4.2.15.Final.jar
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
145 changes: 0 additions & 145 deletions framework/patches/hibernate-4.1.x.Final.patch

This file was deleted.

6 changes: 0 additions & 6 deletions framework/patches/hibernate-4.1.x.Final.patch.README

This file was deleted.

6 changes: 6 additions & 0 deletions framework/patches/hibernate-4.2.15-patch-play.README
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
----
Download Hibernate 4.2.15.Final source code, apply the patch, and build with gradle (tip use export GRADLE_OPTS=-Xmx1G -XX:MaxPermSize=512m)
----

DRY RUN -> patch --dry-run -p1 -i hibernate-4.2.15-patch-play.patch
APPLY -> patch -p1 -i hibernate-4.2.15-patch-play.patch
80 changes: 49 additions & 31 deletions framework/src/play/db/jpa/JPABase.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.exception.GenericJDBCException;
import org.hibernate.internal.SessionImpl;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;

import play.PlayPlugin;
import play.exceptions.UnexpectedException;

import javax.persistence.*;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -133,40 +138,44 @@ private void saveAndCascade(boolean willBeSaved) {
}
if (doCascade) {
Object value = field.get(this);
if (value == null) {
continue;
}
if (value instanceof PersistentMap) {
if (((PersistentMap) value).wasInitialized()) {
if (value != null) {
if (value instanceof PersistentMap) {
if (((PersistentMap) value).wasInitialized()) {

cascadeOrphans(this, (PersistentCollection) value, willBeSaved);
cascadeOrphans(this, (PersistentCollection) value, willBeSaved);

for (Object o : ((Map) value).values()) {
saveAndCascadeIfJPABase(o, willBeSaved);
for (Object o : ((Map) value).values()) {
saveAndCascadeIfJPABase(o, willBeSaved);
}
}
}
continue;
}
if (value instanceof PersistentCollection) {
if (((PersistentCollection) value).wasInitialized()) {
} else if (value instanceof PersistentCollection) {
PersistentCollection col = (PersistentCollection) value;
if (((PersistentCollection) value).wasInitialized()) {

cascadeOrphans(this, (PersistentCollection) value, willBeSaved);

cascadeOrphans(this, (PersistentCollection) value, willBeSaved);
for (Object o : (Collection) value) {
saveAndCascadeIfJPABase(o, willBeSaved);
}
} else {
cascadeOrphans(this, col, willBeSaved);

for (Object o : (Collection) value) {
saveAndCascadeIfJPABase(o, willBeSaved);
}
}
} else if (value instanceof Collection) {
for (Object o : (Collection) value) {
saveAndCascadeIfJPABase(o, willBeSaved);
}
} else if (value instanceof HibernateProxy && value instanceof JPABase) {
if (!((HibernateProxy) value).getHibernateLazyInitializer().isUninitialized()) {
((JPABase) ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation())
.saveAndCascade(willBeSaved);
}
} else if (value instanceof JPABase) {
((JPABase) value).saveAndCascade(willBeSaved);
}
continue;
}
if (value instanceof HibernateProxy && value instanceof JPABase) {
if (!((HibernateProxy) value).getHibernateLazyInitializer().isUninitialized()) {
((JPABase) ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation()).saveAndCascade(willBeSaved);
}
continue;
}
if (value instanceof JPABase) {
((JPABase) value).saveAndCascade(willBeSaved);
continue;
}
}
}
Expand All @@ -178,15 +187,24 @@ private void saveAndCascade(boolean willBeSaved) {
private void cascadeOrphans(JPABase base, PersistentCollection persistentCollection, boolean willBeSaved) {
String dbName = JPA.getDBName(this.getClass());

PersistenceContext pc = ((SessionImpl) JPA.em(dbName).getDelegate()).getPersistenceContext();
SessionImpl session = ((SessionImpl) JPA.em(dbName).getDelegate());
PersistenceContext pc = session.getPersistenceContext();
CollectionEntry ce = pc.getCollectionEntry(persistentCollection);

if (ce != null) {
EntityEntry entry = pc.getEntry(base);
if (entry != null) {
Collection orphans = ce.getOrphans(entry.getEntityName(), persistentCollection);
for (Object o : orphans) {
saveAndCascadeIfJPABase(o, willBeSaved);
CollectionPersister cp = ce.getLoadedPersister();
if (cp != null) {
Type ct = cp.getElementType();
if (ct instanceof EntityType) {
EntityEntry entry = pc.getEntry(base);
String entityName = entry.getEntityName();
entityName = ((EntityType) ct).getAssociatedEntityName(session.getFactory());
if (ce.getSnapshot() != null) {
Collection orphans = ce.getOrphans(entityName, persistentCollection);
for (Object o : orphans) {
saveAndCascadeIfJPABase(o, willBeSaved);
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import java.util.ArrayList;
import java.util.List;

Expand All @@ -15,5 +17,7 @@ public class BaseModel extends Model {

@OneToMany(mappedBy = "baseModel", cascade = CascadeType.ALL, orphanRemoval = true)
public List<LevelOne> levelOnes = new ArrayList<LevelOne>();


@ManyToOne
public LevelOne parent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public class LevelOne extends Model {
@OneToMany(mappedBy = "levelOne", cascade = CascadeType.ALL, orphanRemoval = true)
public List<LevelTwo> levelTwos = new ArrayList<LevelTwo>();

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
public List<BaseModel> children = new ArrayList<BaseModel>();
}
41 changes: 41 additions & 0 deletions samples-and-tests/just-test-cases/app/models/zoo/Animal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package models.zoo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.PreRemove;

import play.db.jpa.JPA;
import play.db.jpa.Model;

@Entity
public class Animal extends Model {

@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER , orphanRemoval = true)
public List<Meal> meals;

public Animal() {
this.meals = new ArrayList<>();
meals.add(new Meal());
}

@PreRemove
protected void clean() {
// hack to force removal of activity instances, otherwise deleting the
// tiers instance fails because the join table still references
// the activity instances that have not been correctly deleted =>
// Hibernate bug that seems to be fixed in Hibernate 4.2.7 and 4.3
// see https://hibernate.atlassian.net/browse/HHH-6484
final String cn = this.getClass().getSimpleName();
final String query = String.format("DELETE FROM %s_%s WHERE %s_id=%s",
cn, Meal.class.getSimpleName(), cn, id);
//JPA.em().createNativeQuery(query).executeUpdate(); // but this hack
// causes a StackOverflowException in Play 1.3RC1
}

}
10 changes: 10 additions & 0 deletions samples-and-tests/just-test-cases/app/models/zoo/Meal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package models.zoo;

import javax.persistence.Entity;

import play.db.jpa.Model;

@Entity
public class Meal extends Model {

}
19 changes: 19 additions & 0 deletions samples-and-tests/just-test-cases/app/models/zoo/Zoo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package models.zoo;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToOne;

import play.db.jpa.Model;

@Entity
public class Zoo extends Model {

@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval = true)
public Animal lion;

public Zoo() {
}

}
Loading

0 comments on commit 6011111

Please sign in to comment.