I would like to evaluate JPA on an existing project. The database model and the java classes exists and are currently mapped via self generated code. The database model and the java classes do not fit ideally together – but the custom mapping works well. Nevertheless the usage of JPA in general seems worth a try.
As you see I am new to JPA and have to do the work with xml configuration. Currently I am working on a one-to-many unidirectional relationship using a join table (please do not discuss this szenario here).
A (one - relationship owner) <-> AB (JoinTable) <-> B (many)
The tables look like this
A
--
ID
BREF
...
B
--
ID
...
AB
--
A_BREF (foreign key to a reference column in A which is NOT the id)
B_ID
I would like to define a unidirectional one-to-many relationship for class A.
class A {
private List<B> bs;
}
and did it like this:
<one-to-many name="bs">
<join-table name="ab">
<join-column name="a_bref">
<referenced-column-name name="bref" />
</join-column>
<inverse-join-column name="b_id">
<referenced-column-name name="id" />
</inverse-join-column>
</join-table>
</one-to-many>
Althoug this does not force an error it is not working. The problem is that the join table does not work on the ID column of A. The query to select the “B” entities works with the A.ID column value instead of the A.BREF column value to select the entities.
(How) can I make this mapping work (I use eclipselink 2.2.0)?
Thanks for any suggestion!
EDIT:
After looking at a link provided in @SJuan76 answer I slightly modified my mapping to
<one-to-many name="bs">
<join-table name="ab">
<join-column name="a_bref" referenced-column-name="bref" />
<inverse-join-column name="b_id" referenced-column-name="id" />
</join-table>
</one-to-many>
This now causes the following errors (tested with eclipselink 2.1.0 and 2.2.0)
eclipselink 2.1.0
Exception Description: The parameter
name [bref] in the query’s selection
criteria does not match any parameter
name defined in the query.
eclipselink 2.2.0
Exception Description: The reference
column name [bref] mapped on the
element [field bs] does not
correspond to a valid field on the
mapping reference.
By the way – if I remove the referenced-column-name="bref" from the definition I get the same exception for the referenced-column-name="id" on the inverse-join-column element. So I doubt that I have understood referenced-column-name correct. I used it to specify the database column name of the tables which are related to the join table. Is this correct?
SOLUTION:
The final error in my szenario was that I did not have the BREF field definied in my class
class A {
private long bref; // missing !
private List<B> bs;
}
and in my orm.xml mapping file for this class
<basic name="bref">
<column name="bref" />
</basic>
I was not aware that I have to define the used join mapping referenced-column-name attributes somewhere in my mapping classes (as I also did not have the join-table itself or the name attributes of join-column/inverse-join-column mapped to a class or class members.)
Also the tip to check the case issue was helpful for me. I feel now quite to verbose in specifying my mapping as I overwrite all default (uppercase) mappings with lowercase values. As my database is not case sensitive I will use upper case notation if special mapping is needed to go with the default.
+1 for all!
Can you try defining the field as “BREF” or the same exact case used if you defined it on the attribute mapping, or you can try setting the eclipselink.jpa.uppercase-column-names persistence property to true. This is likely the issue with “id” when referenced-column-name=”bref” is removed, since it is likely the field in the entity defaults to “ID”.