0

I'm building an application based on JavaEE7 with JPA 2.1 and EJB 3.2. I'm trying to define entity with JPA based on the table from an Oracle database. I use EclipseLink as implementation of JPA.

My case is to retrieve translation stored on the database. All the translation are stored on a single table and identified with a key and a language id.

I can't change the way the database is organised and I'm a beginner in JPA.


Here an example of lines from the translation table:

TRANSLATION:

TRANS_ID | TRANS_KEY                     | TRANS_VALUE | LAN_ID
1        | APPVERSION_APPV_COMMENT_1215  | Du texte    | 1
2        | APPVERSION_APPV_COMMENT_1215  | Some text   | 2

Where LAN_ID : 1 correspond to the french translation and LAN_ID : 2 is the english translation.

The entity of TRANSLATION looks like this:

@Entity
@Table(name = "TRANSLATION")
@NamedQueries({
    @NamedQuery(name="Translation.findAll", query="SELECT trans FROM Translation trans")
})
public class Translation implements Serializable {

    @Id
    @Column(name = "TRANS_ID", nullable = false)
    private Integer translationId;

    @Column(name = "TRANS_KEY", nullable = false)
    private String translationKey;

    @Column(name = "TRANS_VALUE")
    private String translationValue;

    @Column(name = "LAN_ID", nullable = false)
    private Integer languageId;

}

And here is a possible case for a table using translations:

APPVERSION :

APPV_ID | APPV_COMMENT
0       | APPVERSION_APPV_COMMENT_1215
1       | (null)
2       | some texte with no reference to translation table

Here are the tree possible case I can have in column witch use translation. The third case is due to historical reasons.

I would like to implement a JPA entity to represent the table APPVERSION where I could retrieve the translation without using JPQL.

I tried an entity looking like this (simplified version):

@Entity
@Table(name = "APPVERSION")
@NamedQueries({
    @NamedQuery(name="AppVersion.findAll", query="SELECT app FROM AppVersion app")
})
public class AppVersion implements Serializable {

    @Id
    @Column(name = "APPV_ID", nullable = false)
    private Integer applicationVersionId;

    @OneToMany()
    @JoinColumn(name = "TRANS_KEY", referencedColumnName = "APPV_COMMENT", nullable = true)
    //As a beginer who don't get it all I also tryed the following. With quite the same result
    //@JoinColumn(name = "APPV_COMMENT", referencedColumnName = "TRANS_KEY", nullable = true)
    private List<Translation> applicationVersionComment;

}

With, the following

@JoinColumn(name = "TRANS_KEY", referencedColumnName = "APPV_COMMENT", nullable = true)

I got an error saying:

Caused By: Exception [EclipseLink-6094] (Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3): org.eclipse.persistence.exceptions.QueryException
Exception Description: The parameter name [APPV_COMMENT] in the query's selection criteria does not match any parameter name defined in the query.

And with the following

@JoinColumn(name = "APPV_COMMENT", referencedColumnName = "TRANS_KEY", nullable = true)

I got an error saying:

Caused By: Exception [EclipseLink-6094] (Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3): org.eclipse.persistence.exceptions.QueryException
Exception Description: The parameter name [TRANS_KEY] in the query's selection criteria does not match any parameter name defined in the query.

I would like to know how to handle such case with JPA entity. For historical reason the data are quite messy and sadly I have to deal with it as it is.

Cœur
  • 37,241
  • 25
  • 195
  • 267
MaximeL
  • 63
  • 1
  • 7
  • Can you post your `Translation` entity? – Madhusudana Reddy Sunnapu Apr 07 '16 at 10:23
  • 1
    By the way, what is the jpa vendor implementation you are using. [JPA spec](http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf) by itself doesn't support non primary to be used in the JoinColumn annoation. It says _Support for referenced columns that are not primary key columns of the referenced table is optional.Applications that use such mappings will not be portable._ – Madhusudana Reddy Sunnapu Apr 07 '16 at 10:36
  • you have name and referencedColumnName mixed up. should be ```@JoinColumn(name = "APPV_COMMENT", referencedColumnName = "TRANS_KEY", nullable = true)``` – Vladimir Apr 07 '16 at 10:48
  • @MadhusudanaReddySunnapu & @Vladimir I've updated the post to give you more informations. Also I use EclipseLink as provider. `org.eclipse.persistence.jpa.PersistenceProvider` – MaximeL Apr 07 '16 at 12:35
  • @Altrollique you may want to check if eclipseLink supports `non primary key to be used in the JoinColumn annotation. Per JPA spec it is not mandatory. – Madhusudana Reddy Sunnapu Apr 07 '16 at 12:39
  • @MadhusudanaReddySunnapu Well looks like it's an optional feature that EclipseLink doesn't support... Thanks for pointing me that. Is there a way using secondary table or something else I don't know, instead of join column ? – MaximeL Apr 07 '16 at 12:50
  • @Altrollique Franky, not sure as I have never used EclipseLink, but I know for fact that Hibernate supports non PK in the JoinColumn annotation. – Madhusudana Reddy Sunnapu Apr 07 '16 at 12:54
  • @MadhusudanaReddySunnapu ok thank you. I'll look what I can do with Hibernate. But I'll wait to see if someone can give me a way to achieve this with EclipseLink. – MaximeL Apr 07 '16 at 13:00

0 Answers0