5 Replies Latest reply on Jun 22, 2009 8:14 AM by Wolfgang Knauf

    Attribute from MappedClass as a part of composit PK ?

    Dalibor Kalna Newbie

      Hi there,

      I have following problem: I have abstract class, which is @MappedSuperclass and there I have (among others) attribute timestamp, which is common for all my entities.

      Now in entity class (which extends abstract class) I need to define composite primary key, but that timestamp attribute from abstract class should be part of composite primary key. How do I do that?

      Thanks a lot for help.
      Dalibor

        • 1. Re: Attribute from MappedClass as a part of composit PK ?
          Wolfgang Knauf Master

          Hi,

          I am not sure whether the following works, but I would suggest that you use an EmbedddId for your primary key. This way, you have to create an Embeddable class, and you have to duplicate the timestamp ID property to the embeddable class.

          The only problem with this approach is that this would duplicate the field in insert/update statements.
          So you have to annotate the timestamp property in the embeddable class this way:

          @Embeddable
          public class MyId implements Serializable
          {
           @Column(name="...", insertable=false, updateable=false)
           public TimeStamp getSomething()
           {
           ...
           }
           @Column(...)
           public Integer getOtherIdFields()
           {
           ...
           }
          }


          Hope this works and helps ;-)

          Wolfgang

          • 2. Re: Attribute from MappedClass as a part of composit PK ?
            Dalibor Kalna Newbie

            Hi Wolfgang, thanks a lot, I'll try that and let you now if it works.

            • 3. Re: Attribute from MappedClass as a part of composit PK ?
              Dalibor Kalna Newbie

              Hi, it works, well at least it deploys. But how to make sure those two attributes are in sync? Any ideas?

              • 4. Re: Attribute from MappedClass as a part of composit PK ?
                Wolfgang Knauf Master

                Hi,

                you have to synchronize them yourself. So the setter of one attribute has to update the other. This might be a problem for the embedded id, because it cannot set it's timestamp value to the outer class.
                But you might add a "@PreUpdate" callback method to your entity and synchronize both values.

                Hope this helps

                Wolfgang

                • 5. Re: Attribute from MappedClass as a part of composit PK ?
                  Wolfgang Knauf Master

                  Hi Dalibor,

                  one more idea, which might prevent you from duplicating the fields:

                  Instead of an EmbeddedId, use an IdClass (annotate the entity with "IdClass"). This class will have the same fields as the EmbeddedId, but no further annotations.
                  All primary key fields are part of your entity. The timestamp property has to be copied to the subclass, best with an @Override annotation, and getter/setter just call the base class methods.

                  Here is a snippet:

                  public class MyId implements Serializable
                  {
                   public TimeStamp getSomething()
                   {
                   ...
                   }
                   public Integer getOtherIdFields()
                   {
                   ...
                   }
                  }
                  
                  @IdClass(value=MyId.class)
                  public MyEntity extends BaseEntity implements Serializeable
                  {
                   @Id
                   @Override
                   public TimeStamp getSomething()
                   {
                   return super.getSomething();
                   }
                   ...setter...
                  


                  The ID class is required to make "entityManager.find" work, and inserting of entities will not work without. So you need the ID class even if your code does not need it.

                  Hope this helps (and works ;-) )

                  Wolfgang