1 Reply Latest reply on Jan 29, 2007 3:35 PM by fhh

    Up-/Downcasting from objects with partial db-update

      Hi,

      I´ve got two objects, that are extended from each other. For example they look like this:

      @Entity
      @Table(name = "users")
      @Name("user")
      @Scope(ScopeType.SESSION)
      public class User implements Serializable {
      
       @Column(name = "create_date", nullable = false)
       @Temporal(TemporalType.TIMESTAMP)
       private Date createDate;
      
       @Length(min=6)
       @Column(name = "password", nullable = false)
       private String password;
      
       @Column(name = "name", nullable = false)
       private String name;
      
      ....
      }
      
      @Entity
      @Table(name = "extendedUser")
      @Name("publisher")
      @Scope(ScopeType.SESSION)
      public class ExtendedUser extends User implements Serializable {
      
       @Column(name = "upgrade_date", nullable = false)
       @Temporal(TemporalType.TIMESTAMP)
       private Date upgradeDate;
      
      ....
      }
      


      I´ve also got 2 tables. One holds all the attributes for the user and the other one holds only the additional attributes of the extendedUser all with the same primaryKey. What I would like to do now is to upcast my User to an ExtendedUser, so that it keeps all the values in the user-table and creates an entry in my extended-users table with all additional values of the extended object.

      When I simply upcast my object and try to persist it with an em.merge(extendedUser) I get an Exception because it tries to persist a completely new extendedUser, which is absolutely correct, because it should only add the additional values and not create a new entry.

      Is there a way to do an upcast/downcast and adding/deleting only the additional attributes of the inherited objects?

      Thanks for your help

      Thomas

        • 1. Re: Up-/Downcasting from objects with partial db-update

          You cannot do that. I do not mean you cannot do that with JPA but you cannot do that in Java (or any other sane programming language).

          You can upcast refernces to objects but not the objects themsleves, eg.

          
          public class Human {
          }
          
          public class Man extends Human {
          
           private String name;
          
           public Man(String name) {
           this.name = name;
           }
          
          }
          
          Human being = new Man("Adam");
          Man adam = (Man)being;
          
          


          This will work because "being" always references an object of the class Man. But you want to do something like:

          Human being = new Human();
          Man adam = (Man)being;
          


          This will not work because the referenced object "being" is just a human - not yet a man. Changing the object class after creation would put the object in an undefined state - in this example you would have a man without name.

          So you cannot do what you want to do without copying the values. The easiest way is to create a constructor which takes the subclass object as an argument:

          public class Man extends Human {
          
           private String name;
          
           public Man(Human human, String name) {
           super();
           this.inheritedValue = human.inheritedValue;
           this.name = name;
           }
          
           public Man(String name) {
           this.name = name;
           }
          }
          


          However, I would not recommend resusing the id - eben if it might be possible. You are dealing with a new object here so I would rather delete the old one and then insert the new one.

          Regards

          Felix