5 Replies Latest reply on Apr 8, 2008 4:33 PM by jeff.rosen

    How to save entities with PrimaryKeyJoinColumn?

    drathnow


      Could someone give me some insight into the correct way to save entities that are joined over their primary key?

      I have two entities: Field and FieldAccess. They both share the same primary key and have a relation over their primary key:


      class Field {

      @OneToOne (mappedBy = "field")
      protected FieldAccess fieldAccess;

      }

      class FieldAccess {

      @OneToOne
      @PrimaryKeyJoinColumn(name = "fieldid", referencedColumnName = "fieldid")
      protected Field field;
      }

      I'm using Oracle Sequences to generate primary keys.

      When saving a new entity, how does the primary key get propagated from one entity to the other? I've tried the following but the primary keys never end up being the same:

      FieldAccess fieldAccess = new FieldAccess();
      entityManager.persist(fieldAccess);

      Field field = new Field();
      field.setFieldAccess(fieldAccess);
      fieldAccess.setField(field);
      entityManager.persist(field);

      What am I missing?

        • 1. Re: How to save entities with PrimaryKeyJoinColumn?
          itsme

          Hi,

          how are the id fields of both classes defined?

          Normally sequences generate keys as per call. So both entities are serialized to different tables and for this, they get different id values. Only the referencing field must have the same value.

          • 2. Re: How to save entities with PrimaryKeyJoinColumn?
            drathnow

            But the referencing key is the primary key of the entity. Isn't that what @PrimaryKeyJoinColumn is suppose to imply? I would've assumed there would be some way for the implementation to realize this and setup the keys appropriately.

            I've tried a couple of different strategies all with the same results. But here is what I've got now:

            public class Field {

            @Id
            @SequenceGenerator(name = "fieldname_seq", sequenceName = "fieldname_seq")
            @GeneratedValue(strategy = SEQUENCE, generator = "fieldname_seq")
            private long fieldId;

            }


            public class FieldAccess {

            @Id
            private long fieldId;
            }



            • 3. Re: How to save entities with PrimaryKeyJoinColumn?
              itsme

              ejb3-persistence spec only says, that @PrimaryKeyJoinColumn gives you the ability to name the corresponding column name different then the referenced column name in the child entity table.

              So both entities find each other by the referenced column. This column is created as an additional column at the childs table referencing the primary key of the parents table.

              • 4. Re: How to save entities with PrimaryKeyJoinColumn?
                drathnow

                I have to admit that I've not read the spec but I've read a couple of books that say the PrimaryKeyJoinColumn joins entities over their primary keys, no other columns are involve.

                If what you're saying is true, how is this different than a OneToOne relationship? What you're describing sounds to me like a OneToOne relationship.

                • 5. Re: How to save entities with PrimaryKeyJoinColumn?
                  jeff.rosen

                  I'm taking a wild guess here, but you're defining 2 entities that have a one-to-one relationship and are joined by their primary keys, so have you implemented those semantics in your java classes? For example, what happens if I call setFieldId on Field, does it's associated FieldAccess instance have it's fieldId kept in sync? What about vice versa? And for the getters?

                  Given the life-cycles of each type, can you get by with a single fieldId property in just one of the classes?