2 Replies Latest reply on May 29, 2007 10:18 AM by wayne baylor

    Merging an extended class from existing superclass

    Reuben Helms Newbie

      Hi all

      I'm fairly new at the EJB3/JPA stuff, and I'm writing an app that has some legacy data that cant be moved around too much.

      I have a table and class, Dog (for simplicity) that is populated via another application. This can exist as an instance in its own right.

      I also have a class SpottedDog that is an extension of Dog. Because I cant play with the Dog table too much, I'm using an additional table for the SpottedDog properties and have tried using SecondaryTable and the table per subclass.

      The aim is to try and create a SpottedDog from an existing Dog, and keep the unique identifier on the Dog record.

      I create a new SpottedDog and assign values from the Dog to it in the constructor, and then call em.merge(spottedDog);.

      However, the Hibernate debugging shows that it tries to search on SpottedDog with a inner join on Dog. Because a SpottedDog record does not exist yet, it assumes that the Dog entry doesnt either, and proceeds to try to insert a Dog entry. This ends up causing an identity insert error, because its trying to do that Dog insert that doesnt need to be done.

      So, any tips for extending an object to a subclass, where it will recognise that the superclass already exists?

      For this particular case, it would be nice if the original search was a left outer join on Dog, so that the Dog record would be recognised and only an insert on the SpottedDog would be required. I guess an additional search on Dog instead of the left outer join would do just as well.

        • 1. Re: Merging an extended class from existing superclass
          Carlo de Wolf Master

          Reconsider the livecycle of your object. For example:

          Dog dog = new Dog("Tom");
          <do magic here>
          assert dog instanceof SpottedDog : "magic failed";

          I can't think of any magic that won't fail.

          So the only solution is to make the SpottedDog an one on one association with Dog.
          The code will then be some like:
          @Entity
          public class SpottedDog {
           @Id Long id;
          
           @OneToOne @PrimaryKeyColumnJoin
           Dog dog;
          }

          You may need to fully specify the one to one relationship as it may be an one way association.

          • 2. Re: Merging an extended class from existing superclass
            wayne baylor Apprentice

            I think there is a conceptual issue here. What you are trying is analogous to casting a Dog object to a SpottedDog object, which is bad--a Dog is not always a SpottedDog.

            I suggest you remove the existing Dog object, then save the SpottedDog object.

            For example:

            Dog d = em.find(Dog.class, ID);
            SpottedDog sd = new SpottedDog(d);
            sd.set*(...);
            ...
            em.remove(d);
            em.persist(sd); //you could also use em.merge(sd) here