#1410 inprogress
Oskari Porkka

GenericModel.edit replaces Hibernate's persistent collections by non-persistent ones

Reported by Oskari Porkka | February 3rd, 2012 @ 03:33 PM | in 1.4.x

I posted this one on Play Google group as well: https://groups.google.com/d/msg/play-framework/XzmWO5Nff3M/V5_ZZDSa...

My Play framework version is 1.2.4 run on Windows.

The GenericModel.edit method that is used by JPABinder replaces persistent collection objects (Hibernate PersistentBag, PersistentSet) by non-persistent collection objects (ArrayList, HashSet). When the owner entity of those collections is saved, the changes to the collections are not saved because the collections are not persistent anymore.

I'm saving rather complicated entities on a single form. The entity has a collection of subentities which in turn has again a collection of sub sub entities. It something like this:

class Entity extends Model {
    public String field;
    @OneToMany(cascade = CascadeType.ALL)
    public List<SubEntity> subEntities;
} 

class SubEntity extends Model {
    public String subField;
    @OneToMany(cascade = CascadeType.ALL)
    public List<SubSubEntity> subSubEntities;
}

class SubSubEntity extends Model {
   public String subSubField;
}

My edit form uses Controller method update to save the entities:

public static void update(Entity entity) {
    entity.save();
}

I send parameters like:

entity.id = 1;
entity.field = fieldValue;

entity.subEntities[0].id = 10
entity.subEntities[0].subField = subFieldValue0

entity.subEntities[1].id = 11
entity.subEntities[1].subField = subFieldValue1

entity.subEntities[0].subSubEntities[0].id = 100
entity.subEntities[0].subSubEntities[1].id = 101

entity.subEntities[1].subSubEntities[0].id = 110
entity.subEntities[1].subSubEntities[1].id = 111

.. and so on.

The JPAPlugin does good job in fetching the Entity[1] and its collections from the database and applying the change to entity.field. It however, cannot properly apply the changes to the collections. The entity.subEntities list is originally a Hibernate PersistentBag, but it is replaced by a regular ArrayList. Same happens to subSubEntities lists. This causes problems with saving. On entity.save() I get the following error

A java.lang.RuntimeException has been caught, java.util.concurrent.ExecutionException: play.exceptions.JavaExecutionException: org.hibernate.PersistentObjectException: detached entity passed to persist: models.SubEntity

I think it should be possible to save OneToMany subEntities and even subSubEntities.

There is a test application as an attachment.

The ticket number #1395 is related to this issue.

Comments and changes to this ticket

  • Nicolas Leroux

    Nicolas Leroux February 9th, 2012 @ 10:08 PM

    • State changed from “new” to “confirmed”
    • Assigned user set to “Nicolas Leroux”
    • Milestone set to 1.2.5
    • Milestone order changed from “1022” to “0”
  • Morten Kjetland

    Morten Kjetland February 12th, 2012 @ 02:14 PM

    • State changed from “confirmed” to “duplicate”

    Duplicate of #1395

  • Nicolas Leroux

    Nicolas Leroux May 11th, 2012 @ 07:08 PM

    • State changed from “duplicate” to “confirmed”
    • Milestone order changed from “17” to “0”

    Reopen as I don't think it is a duplicate of #1395. However it should be fixed.

  • Nicolas Leroux

    Nicolas Leroux May 11th, 2012 @ 07:20 PM

    • State changed from “confirmed” to “inprogress”
  • Jan Tammen

    Jan Tammen May 11th, 2012 @ 07:32 PM

    (from #1395)

    Is you problem exactly the same as #1410? (btw let's talk on #1410)

    Yes, it's basically the same. Although I don't have a SubSubEntity, only an Entity with a @OneToMany relationship (managed by Hibernate) to a SubEntity.

    Models:

    @Entity
    public class MyEntity extends Model {
        @Valid
        @Required
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "entity")
        public List<SubEntity> subEntities;
    }
    
    @Entity
    public class SubEntity extends Model {
        @ManyToOne(optional = false)
        public MyEntity entity;
    }
    

    Controller:

    public class TestController extends Controller {
        public static void save(@Valid final MyEntity entity) {
            entity.save();
        }
    }
    

    In the view I set parameters like:

    entity.id = 1
    entity.subEntities[0].id = 1
    entity.subEntities[1].id = 2
    

    and so on.

  • Nicolas Leroux

    Nicolas Leroux May 13th, 2012 @ 09:23 PM

    I have to think about that one since it is really not trivial. The hibernate error is indeed correct.

  • Nicolas Leroux

    Nicolas Leroux May 13th, 2012 @ 10:02 PM

    • State changed from “inprogress” to “wontfix”

    Thiking of it I think you should entity.merge() instead of entity.save() since your entity is attached.

  • Nicolas Leroux

    Nicolas Leroux May 13th, 2012 @ 10:21 PM

    • State changed from “wontfix” to “opinion”
  • Nicolas Leroux

    Nicolas Leroux May 13th, 2012 @ 10:43 PM

    • State changed from “opinion” to “inprogress”
  • Jan Tammen

    Jan Tammen May 14th, 2012 @ 10:28 AM

    Hi Nicolas,

    thanks for your proposal - I gave it a quick try and stumbled upon another error: my Entity has a play.db.jpa.Blob member, which does not seem support merging - play.db.jpa.Blob.replace() throws an UnsupportedOperationException.

    Will try it later this day without the Blob again and report the outcome.

    Greets,
    Jan.

  • Oskari Porkka

    Oskari Porkka May 14th, 2012 @ 10:32 AM

    The problem is that the Play Binder (or GenericModel.edit) replaces Hibernate's PersistentBag object for entity.subEntities collection completely by a new HashSet/ArrayList. There is not reference available to the original Hibernate collection anymore and thus entity.merge does not do anything for that collection.

  • Jan Tammen

    Jan Tammen May 14th, 2012 @ 12:15 PM

    As Oskari's comment suspects, using merge() does not solve the problem - now the PersistentObjectException is gone but the sub entity collection does not get saved because it is not a Hibernate collection at all.

    I found a workaround at the end of this SO question which rebinds the collection. It seems to work, but I guess/hope that there is a real and more robust solution to that problem...

  • Nicolas Leroux

    Nicolas Leroux May 29th, 2012 @ 10:00 AM

    • Milestone changed from 1.2.5 to 1.3
    • Milestone order changed from “24” to “0”
  • Nicolas Leroux

    Nicolas Leroux May 29th, 2012 @ 10:00 AM

    • no changes were found...
  • Ron Gross

    Ron Gross May 29th, 2012 @ 11:16 AM

    Note that this is a regression over 1.2.4 / mbknor-3, at least according to my experience.
    When I upgraded from mbknor-3 to one of the latest/RC 1.2.5, this bug happened.

    Would it be possible to schedule this in 1.2.5.1/1.2.6 instead of 1.3?
    After the long delay between 1.2.4 and 1.2.5, I would hate to wait several months more for this fix to be released in an official build.

  • Nicolas Leroux

    Nicolas Leroux May 29th, 2012 @ 11:22 AM

    I actually have a fixed for that one but it changes the cascading behavior, that is why I decided to not include it.

    I am not sure we are talking about the same bug, since this bug exists since 1.2.0.
    Do you have a test case where it works in 1.2.4 and does not work in 1.2.5RC3? I will gladly fix it for the 1.2.5 finale release then. I will release a 1.2.5rc4 anyway since we changed hibernate version between RCs.

  • Ron Gross

    Ron Gross May 29th, 2012 @ 11:28 AM

    I tried reproducing the bug with clean example, but it was a bit difficult to reproduce on a standalone project.

    I'm not 100% certain it's the same bug ... I got different error messages, but the use case is so close that I assumed it is.

    Could you perhaps release a zip with your fix, as an unofficial package, just so I could test if it solves my issue?

    BTW, what is the change in the cascading behavior?

  • notalifeform (at gmail)

    notalifeform (at gmail) April 21st, 2014 @ 08:02 PM

    • Milestone changed from 1.3 to 1.4.x
  • John Bordan

    John Bordan November 1st, 2018 @ 05:12 AM

    Play solitaire times game from here just in click http://solitairetimes.com thid game is a series of spider solitaire game.Try this game this is amazing.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2>Play framework</h2>

Play makes it easier to build Web applications with Java. It is a clean alternative to bloated Enterprise Java stacks. It focuses on developer productivity and targets RESTful architectures. Learn more on the <a href="http://www.playframework.org">http://www.playframework.org</a> website.<br><br>

<h2>Source code is hosted on github</h2>Check out our repository at <a href="http://github.com/playframework/play">http://github.com/playframework/play</a><br><br>

<h2>Contributing, creating a patch</h2> Please read the <a href="http://play.lighthouseapp.com/projects/57987/contributor-guide">contributor guide</a><br><br>

<h2>Reporting Security Vulnerabilities</h2> Since all bug reports are public, please report any security vulnerability directly to <em>guillaume dot bort at gmail dot com</em>.<br><br>

<h2>Creating a bug report</h2> Bug reports are incredibly helpful, so take time to report bugs and request features in our ticket tracker. We’re always grateful for patches to Play’s code. Indeed, bug reports with attached patches will get fixed far quickly than those without any.<br><br>

Please include as much relevant information as possible including the exact framework version you're using and a code snippet that reproduces the problem.<br><br>

Don't have too much expectations. Unless the bug is really a serious "everything is broken" thing, you're creating a ticket to start a discussion. Having a patch (or a branch on Github we can pull from) is better, but then again we'll only pull high quality branches that make sense to be in the core of Play.

Attachments

Referenced by

Pages