You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Marco de Booij <ma...@debooy.eu> on 2015/04/26 17:57:20 UTC

Mapping a Join Table with Additional Columns

I use Tomee 1.7.1 with openjpa version 
openjpa-2.4.0-nonfinal-1598334-r422266.

I have an entity auteurs and an entity boek. They have a ManyToMany 
relation through the entity auteurs_boeken. In this entity there is a 
field type to define the type of the relation (writer, illustrations, 
...). I followed the 
https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany page and came 
up with the following classes (left out all constructors, getters, and 
setters):

=====
@Entity
@Table(name="AUTEURS", schema="BYBLOS")
public class AuteurDto
     extends Dto implements Comparable<AuteurDto>, Cloneable {
   private static final  long  serialVersionUID  = 1L;

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="AUTEUR_ID", nullable=false, unique=true)
   private Long    auteurId;
   @Column(name="NAAM", length=100, nullable=false)
   private String  naam;
   @Column(name="VOORNAAM", length=100)
   private String  voornaam;

   @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, 
mappedBy="auteur")
   private List<AuteurBoekDto> boeken;
}

=====
@Entity
@Table(name="BOEKEN", schema="BYBLOS")
public class BoekDto extends Dto implements Comparable<BoekDto>, Cloneable {
   private static final  long  serialVersionUID  = 1L;

   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="BOEK_ID", nullable=false, unique=true)
   private Long    boekId;
   @Column(name="DEEL", precision=5, scale=0)
   private Integer deel;
   @Column(name="DRUK", precision=3, scale=0)
   private Integer druk;
   @Column(name="ISBN", length=13)
   private String  isbn;
   @Column(name="JAAR_UITGAVE", precision=4, scale=0)
   private Integer jaarUitgave;
   @Column(name="SUBDEEL", length=2)
   private String  subdeel;
   @Column(name="TAAL", length=2, nullable=false)
   private String  taal;
   @Column(name="TITEL", length=100, nullable=false)
   private String  titel;

   @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
   @JoinColumn(name="SERIE_ID", nullable=false, updatable=false)
   private SerieDto  serie;

   @OneToMany(mappedBy="boek", fetch=FetchType.LAZY)
   private List<AuteurBoekDto> auteurs;
}

=====
@Entity
@Table(name="AUTEURS_BOEKEN", schema="BYBLOS")
@IdClass(AuteurBoekPK.class)
public class AuteurBoekDto
     extends Dto implements Comparable<AuteurBoekDto>, Cloneable {
   private static final  long  serialVersionUID  = 1L;

   @Id
   private Long    auteurId;
   @Id
   private Long    boekId;
   @Column(name="AUTEUR_TYPE", nullable=false, length=1)
   private String  auteurType;

   @ManyToOne
   @PrimaryKeyJoinColumn(name="AUTEUR_ID", referencedColumnName="auteurId")
   private AuteurDto auteur;
   @ManyToOne
   @PrimaryKeyJoinColumn(name="BOEK_ID", referencedColumnName="boekId")
   private BoekDto   boek;
}

When I fetch the boeken from within the AuteurDto I get the message:
<openjpa-2.4.0-nonfinal-1598334-r422266:1599166 fatal user error> 
org.apache.openjpa.persistence.ArgumentException: 
"eu.debooy.byblos.domain.AuteurBoekDto.auteur" defines a target of 
"auteurId" for column "AUTEUR_ID", but that target does not exist in 
table "BYBLOS.AUTEURS".
I have the same problem on the BoekDto. BoekDto has a OneToOne relation 
with SerieDto and when I read the boeken from there I get the correct 
boeken so I guess that the problem lies with my implementation of the 
ManyToMany. Can someone show me the way to the correct implementation?

Regards,

Marco

Re: Mapping a Join Table with Additional Columns

Posted by Marco de Booij <ma...@debooy.eu>.
I found it at last. Just misunderstood the referencedColumnName 
attribute. The field has nothing to do with the Java class. Here is the 
working code:

=====
@Entity
@Table(name="AUTEURS_BOEKEN", schema="BYBLOS")
@IdClass(AuteurBoekPK.class)
public class AuteurBoekDto
     extends Dto implements Comparable<AuteurBoekDto>, Cloneable {
   private static final  long  serialVersionUID  = 1L;

   @Id
   @Column(name="AUTEUR_ID", nullable=false, unique=true)
   private Long    auteurId;
   @Id
   @Column(name="BOEK_ID", nullable=false, unique=true)
   private Long    boekId;
   @Column(name="AUTEUR_TYPE", nullable=false, length=1)
   private String  auteurType;

   @ManyToOne
   @JoinColumn(name="AUTEUR_ID", referencedColumnName="AUTEUR_ID")
   private AuteurDto auteur;
   @ManyToOne
   @JoinColumn(name="BOEK_ID", referencedColumnName="BOEK_ID")
   private BoekDto   boek;

Regards,

Marco
Op 27-04-15 om 20:26 schreef Marco de Booij:
> The problem is that the join-table has a field (AUTEUR_TYPE) that I 
> need to fill. With the ManyToMany I do not have this possibility.
>
> Regards,
>
> Marco
>
> Op 27-04-15 om 13:35 schreef Mark Struberg:
>> Why don’t you use a @ManyToMany relation?
>>
>> LieGrue,
>> strub
>>
>>
>>> Am 26.04.2015 um 17:57 schrieb Marco de Booij 
>>> <ma...@debooy.eu>:
>>>
>>> I use Tomee 1.7.1 with openjpa version 
>>> openjpa-2.4.0-nonfinal-1598334-r422266.
>>>
>>> I have an entity auteurs and an entity boek. They have a ManyToMany 
>>> relation through the entity auteurs_boeken. In this entity there is 
>>> a field type to define the type of the relation (writer, 
>>> illustrations, ...). I followed the 
>>> https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany page and 
>>> came up with the following classes (left out all constructors, 
>>> getters, and setters):
>>>
>>> =====
>>> @Entity
>>> @Table(name="AUTEURS", schema="BYBLOS")
>>> public class AuteurDto
>>>     extends Dto implements Comparable<AuteurDto>, Cloneable {
>>>   private static final  long  serialVersionUID  = 1L;
>>>
>>>   @Id
>>>   @GeneratedValue(strategy=GenerationType.IDENTITY)
>>>   @Column(name="AUTEUR_ID", nullable=false, unique=true)
>>>   private Long    auteurId;
>>>   @Column(name="NAAM", length=100, nullable=false)
>>>   private String  naam;
>>>   @Column(name="VOORNAAM", length=100)
>>>   private String  voornaam;
>>>
>>>   @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, 
>>> mappedBy="auteur")
>>>   private List<AuteurBoekDto> boeken;
>>> }
>>>
>>> =====
>>> @Entity
>>> @Table(name="BOEKEN", schema="BYBLOS")
>>> public class BoekDto extends Dto implements Comparable<BoekDto>, 
>>> Cloneable {
>>>   private static final  long  serialVersionUID  = 1L;
>>>
>>>   @Id
>>>   @GeneratedValue(strategy=GenerationType.IDENTITY)
>>>   @Column(name="BOEK_ID", nullable=false, unique=true)
>>>   private Long    boekId;
>>>   @Column(name="DEEL", precision=5, scale=0)
>>>   private Integer deel;
>>>   @Column(name="DRUK", precision=3, scale=0)
>>>   private Integer druk;
>>>   @Column(name="ISBN", length=13)
>>>   private String  isbn;
>>>   @Column(name="JAAR_UITGAVE", precision=4, scale=0)
>>>   private Integer jaarUitgave;
>>>   @Column(name="SUBDEEL", length=2)
>>>   private String  subdeel;
>>>   @Column(name="TAAL", length=2, nullable=false)
>>>   private String  taal;
>>>   @Column(name="TITEL", length=100, nullable=false)
>>>   private String  titel;
>>>
>>>   @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
>>>   @JoinColumn(name="SERIE_ID", nullable=false, updatable=false)
>>>   private SerieDto  serie;
>>>
>>>   @OneToMany(mappedBy="boek", fetch=FetchType.LAZY)
>>>   private List<AuteurBoekDto> auteurs;
>>> }
>>>
>>> =====
>>> @Entity
>>> @Table(name="AUTEURS_BOEKEN", schema="BYBLOS")
>>> @IdClass(AuteurBoekPK.class)
>>> public class AuteurBoekDto
>>>     extends Dto implements Comparable<AuteurBoekDto>, Cloneable {
>>>   private static final  long  serialVersionUID  = 1L;
>>>
>>>   @Id
>>>   private Long    auteurId;
>>>   @Id
>>>   private Long    boekId;
>>>   @Column(name="AUTEUR_TYPE", nullable=false, length=1)
>>>   private String  auteurType;
>>>
>>>   @ManyToOne
>>>   @PrimaryKeyJoinColumn(name="AUTEUR_ID", 
>>> referencedColumnName="auteurId")
>>>   private AuteurDto auteur;
>>>   @ManyToOne
>>>   @PrimaryKeyJoinColumn(name="BOEK_ID", referencedColumnName="boekId")
>>>   private BoekDto   boek;
>>> }
>>>
>>> When I fetch the boeken from within the AuteurDto I get the message:
>>> <openjpa-2.4.0-nonfinal-1598334-r422266:1599166 fatal user error> 
>>> org.apache.openjpa.persistence.ArgumentException: 
>>> "eu.debooy.byblos.domain.AuteurBoekDto.auteur" defines a target of 
>>> "auteurId" for column "AUTEUR_ID", but that target does not exist in 
>>> table "BYBLOS.AUTEURS".
>>> I have the same problem on the BoekDto. BoekDto has a OneToOne 
>>> relation with SerieDto and when I read the boeken from there I get 
>>> the correct boeken so I guess that the problem lies with my 
>>> implementation of the ManyToMany. Can someone show me the way to the 
>>> correct implementation?
>>>
>>> Regards,
>>>
>>> Marco
>>
>
>


Re: Mapping a Join Table with Additional Columns

Posted by Marco de Booij <ma...@debooy.eu>.
The problem is that the join-table has a field (AUTEUR_TYPE) that I need 
to fill. With the ManyToMany I do not have this possibility.

Regards,

Marco

Op 27-04-15 om 13:35 schreef Mark Struberg:
> Why don’t you use a @ManyToMany relation?
>
> LieGrue,
> strub
>
>
>> Am 26.04.2015 um 17:57 schrieb Marco de Booij <ma...@debooy.eu>:
>>
>> I use Tomee 1.7.1 with openjpa version openjpa-2.4.0-nonfinal-1598334-r422266.
>>
>> I have an entity auteurs and an entity boek. They have a ManyToMany relation through the entity auteurs_boeken. In this entity there is a field type to define the type of the relation (writer, illustrations, ...). I followed the https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany page and came up with the following classes (left out all constructors, getters, and setters):
>>
>> =====
>> @Entity
>> @Table(name="AUTEURS", schema="BYBLOS")
>> public class AuteurDto
>>     extends Dto implements Comparable<AuteurDto>, Cloneable {
>>   private static final  long  serialVersionUID  = 1L;
>>
>>   @Id
>>   @GeneratedValue(strategy=GenerationType.IDENTITY)
>>   @Column(name="AUTEUR_ID", nullable=false, unique=true)
>>   private Long    auteurId;
>>   @Column(name="NAAM", length=100, nullable=false)
>>   private String  naam;
>>   @Column(name="VOORNAAM", length=100)
>>   private String  voornaam;
>>
>>   @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="auteur")
>>   private List<AuteurBoekDto> boeken;
>> }
>>
>> =====
>> @Entity
>> @Table(name="BOEKEN", schema="BYBLOS")
>> public class BoekDto extends Dto implements Comparable<BoekDto>, Cloneable {
>>   private static final  long  serialVersionUID  = 1L;
>>
>>   @Id
>>   @GeneratedValue(strategy=GenerationType.IDENTITY)
>>   @Column(name="BOEK_ID", nullable=false, unique=true)
>>   private Long    boekId;
>>   @Column(name="DEEL", precision=5, scale=0)
>>   private Integer deel;
>>   @Column(name="DRUK", precision=3, scale=0)
>>   private Integer druk;
>>   @Column(name="ISBN", length=13)
>>   private String  isbn;
>>   @Column(name="JAAR_UITGAVE", precision=4, scale=0)
>>   private Integer jaarUitgave;
>>   @Column(name="SUBDEEL", length=2)
>>   private String  subdeel;
>>   @Column(name="TAAL", length=2, nullable=false)
>>   private String  taal;
>>   @Column(name="TITEL", length=100, nullable=false)
>>   private String  titel;
>>
>>   @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
>>   @JoinColumn(name="SERIE_ID", nullable=false, updatable=false)
>>   private SerieDto  serie;
>>
>>   @OneToMany(mappedBy="boek", fetch=FetchType.LAZY)
>>   private List<AuteurBoekDto> auteurs;
>> }
>>
>> =====
>> @Entity
>> @Table(name="AUTEURS_BOEKEN", schema="BYBLOS")
>> @IdClass(AuteurBoekPK.class)
>> public class AuteurBoekDto
>>     extends Dto implements Comparable<AuteurBoekDto>, Cloneable {
>>   private static final  long  serialVersionUID  = 1L;
>>
>>   @Id
>>   private Long    auteurId;
>>   @Id
>>   private Long    boekId;
>>   @Column(name="AUTEUR_TYPE", nullable=false, length=1)
>>   private String  auteurType;
>>
>>   @ManyToOne
>>   @PrimaryKeyJoinColumn(name="AUTEUR_ID", referencedColumnName="auteurId")
>>   private AuteurDto auteur;
>>   @ManyToOne
>>   @PrimaryKeyJoinColumn(name="BOEK_ID", referencedColumnName="boekId")
>>   private BoekDto   boek;
>> }
>>
>> When I fetch the boeken from within the AuteurDto I get the message:
>> <openjpa-2.4.0-nonfinal-1598334-r422266:1599166 fatal user error> org.apache.openjpa.persistence.ArgumentException: "eu.debooy.byblos.domain.AuteurBoekDto.auteur" defines a target of "auteurId" for column "AUTEUR_ID", but that target does not exist in table "BYBLOS.AUTEURS".
>> I have the same problem on the BoekDto. BoekDto has a OneToOne relation with SerieDto and when I read the boeken from there I get the correct boeken so I guess that the problem lies with my implementation of the ManyToMany. Can someone show me the way to the correct implementation?
>>
>> Regards,
>>
>> Marco
>


Re: Mapping a Join Table with Additional Columns

Posted by Mark Struberg <st...@yahoo.de>.
Why don’t you use a @ManyToMany relation?

LieGrue,
strub


> Am 26.04.2015 um 17:57 schrieb Marco de Booij <ma...@debooy.eu>:
> 
> I use Tomee 1.7.1 with openjpa version openjpa-2.4.0-nonfinal-1598334-r422266.
> 
> I have an entity auteurs and an entity boek. They have a ManyToMany relation through the entity auteurs_boeken. In this entity there is a field type to define the type of the relation (writer, illustrations, ...). I followed the https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany page and came up with the following classes (left out all constructors, getters, and setters):
> 
> =====
> @Entity
> @Table(name="AUTEURS", schema="BYBLOS")
> public class AuteurDto
>    extends Dto implements Comparable<AuteurDto>, Cloneable {
>  private static final  long  serialVersionUID  = 1L;
> 
>  @Id
>  @GeneratedValue(strategy=GenerationType.IDENTITY)
>  @Column(name="AUTEUR_ID", nullable=false, unique=true)
>  private Long    auteurId;
>  @Column(name="NAAM", length=100, nullable=false)
>  private String  naam;
>  @Column(name="VOORNAAM", length=100)
>  private String  voornaam;
> 
>  @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="auteur")
>  private List<AuteurBoekDto> boeken;
> }
> 
> =====
> @Entity
> @Table(name="BOEKEN", schema="BYBLOS")
> public class BoekDto extends Dto implements Comparable<BoekDto>, Cloneable {
>  private static final  long  serialVersionUID  = 1L;
> 
>  @Id
>  @GeneratedValue(strategy=GenerationType.IDENTITY)
>  @Column(name="BOEK_ID", nullable=false, unique=true)
>  private Long    boekId;
>  @Column(name="DEEL", precision=5, scale=0)
>  private Integer deel;
>  @Column(name="DRUK", precision=3, scale=0)
>  private Integer druk;
>  @Column(name="ISBN", length=13)
>  private String  isbn;
>  @Column(name="JAAR_UITGAVE", precision=4, scale=0)
>  private Integer jaarUitgave;
>  @Column(name="SUBDEEL", length=2)
>  private String  subdeel;
>  @Column(name="TAAL", length=2, nullable=false)
>  private String  taal;
>  @Column(name="TITEL", length=100, nullable=false)
>  private String  titel;
> 
>  @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
>  @JoinColumn(name="SERIE_ID", nullable=false, updatable=false)
>  private SerieDto  serie;
> 
>  @OneToMany(mappedBy="boek", fetch=FetchType.LAZY)
>  private List<AuteurBoekDto> auteurs;
> }
> 
> =====
> @Entity
> @Table(name="AUTEURS_BOEKEN", schema="BYBLOS")
> @IdClass(AuteurBoekPK.class)
> public class AuteurBoekDto
>    extends Dto implements Comparable<AuteurBoekDto>, Cloneable {
>  private static final  long  serialVersionUID  = 1L;
> 
>  @Id
>  private Long    auteurId;
>  @Id
>  private Long    boekId;
>  @Column(name="AUTEUR_TYPE", nullable=false, length=1)
>  private String  auteurType;
> 
>  @ManyToOne
>  @PrimaryKeyJoinColumn(name="AUTEUR_ID", referencedColumnName="auteurId")
>  private AuteurDto auteur;
>  @ManyToOne
>  @PrimaryKeyJoinColumn(name="BOEK_ID", referencedColumnName="boekId")
>  private BoekDto   boek;
> }
> 
> When I fetch the boeken from within the AuteurDto I get the message:
> <openjpa-2.4.0-nonfinal-1598334-r422266:1599166 fatal user error> org.apache.openjpa.persistence.ArgumentException: "eu.debooy.byblos.domain.AuteurBoekDto.auteur" defines a target of "auteurId" for column "AUTEUR_ID", but that target does not exist in table "BYBLOS.AUTEURS".
> I have the same problem on the BoekDto. BoekDto has a OneToOne relation with SerieDto and when I read the boeken from there I get the correct boeken so I guess that the problem lies with my implementation of the ManyToMany. Can someone show me the way to the correct implementation?
> 
> Regards,
> 
> Marco