openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fay Wang <fyw...@yahoo.com>
Subject Re: JPA adding class name to join column name
Date Thu, 25 Feb 2010 20:26:37 GMT
Hi,
    I just realized that you mentioned removing name field will make the problem go away,
and it is undesirable to define all columns in the root class. Can you try the following ValuedCustomer
definition? I added a new field "age" to this class, and also  added the SecondaryTable annotation
to it:

@Entity
@SecondaryTable(
        name="CUSTOMER",
        pkJoinColumns = @PrimaryKeyJoinColumn(
            name="ID", 
            referencedColumnName="ID"))
@DiscriminatorValue(value="2")
public class ValuedCustomer extends Customer implements Serializable {

    @Column(table="CUSTOMER",name="AGE")
    private int age;
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
}


I also modified your Customer.class by taking out the rating field. You don't really need
this rating field because your discriminator and the rating field map to the same column.

@Entity

@Table(name="CUSTOMERRATING")

@Inheritance(strategy=InheritanceType.SINGLE_TABLE)

@SecondaryTables({
     @SecondaryTable(
         name="CUSTOMER",
         pkJoinColumns = @PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")),
     @SecondaryTable(
         name="MORECUSTOMERDATA",
         pkJoinColumns = @PrimaryKeyJoinColumn(name="ID" , referencedColumnName="ID"))
})

@DiscriminatorColumn(name="RATING")
public class Customer implements Serializable {
    @Column(name="ID")
    @Id
    protected String id;
    
    @Column(table="CUSTOMER",name="NAME")
    private String name;


Finally, in your GreatCustomer.java, again your greatCustomerdataId originally is mapped to
the same ID column of the GREATCUSTOMERDATA. However, this ID column is supposed to be the
join column, you should map it to a different column. Otherwise, this value can not be stored.

@Entity
@SecondaryTable(
    name="GREATCUSTOMERDATA",
    pkJoinColumns = @PrimaryKeyJoinColumn(
        name="ID", 
        referencedColumnName="ID"))
        
@DiscriminatorValue(value="9")

public class GreatCustomer extends ValuedCustomer implements Serializable  {
    @Column(table="GREATCUSTOMERDATA",name="GC_ID")
    private String greatCustomerdataId;

With these entity definitions, the tables created by openjpa are:

CREATE TABLE CUSTOMER (ID VARCHAR(254), NAME VARCHAR(254), AGE INTEGER)

CREATE TABLE CUSTOMERRATING (ID VARCHAR(254) NOT NULL, RATING VARCHAR(31), PRIMARY KEY (ID))

CREATE TABLE GREATCUSTOMERDATA (ID VARCHAR(254), GC_ID VARCHAR(254))

Fay



----- Original Message ----
From: Fay Wang <fyw300@yahoo.com>
To: users@openjpa.apache.org
Sent: Thu, February 25, 2010 11:11:57 AM
Subject: Re: JPA adding class name to join column name

Hi,
   I noticed that you have "name" field in your Customer.java and ValuedCustomer.java. This
field in both classes is mapped to the same column in the same table. Since ValuedCustomer
inherits from Customer, I am wondering why you need to have a separate "name" field in the
ValuedCustomer. If you take out this field from the ValuedCustomer, this column VALUEDCUSTOMER_ID
will not be generated. 

Fay



----- Original Message ----
From: "openjpa@reider.net" <openjpa@reider.net>
To: users@openjpa.apache.org
Sent: Wed, February 24, 2010 6:52:30 PM
Subject: JPA adding class name to join column name

I'm having an issue with JPA generating column names containing Java
class names, with some mix of
@Inheritance(strategy=InheritanceType.SINGLE_TABLE and
@SecondaryTables. This results in an error because of a non existent
column:

<openjpa-1.2.2-SNAPSHOT-r422266:821449 nonfatal general error>
org.apache.openjpa.persistence.PersistenceException: DB2 SQL error:
SQLCODE: -206, SQLSTATE: 42703, SQLERRMC: T1.VALUEDCUSTOMER_ID
1607819221 SELECT ... FROM CUSTOMERRATING t0 INNER JOIN CUSTOMER t1 on
t0.ID = t1.VALUEDCUSTOMER_ID INNER JOIN GREATCUSTOMERDATA t2 ON t0.id
= t2.id  ...

ValuedCustomer is the class of one of the Java entities on the table.
Why would JPA prefix the column name with the class name
(VALUEDCUSTOMER_ID)?  The column name is just ID. The error goes away
when removing the name field from ValuedCustomer class. It can be
undesirable to have to define all columns in the root class. I did try
copying down the @SecondaryTables annotation but it didnt help.

This entity is being migrated from TOPLink (11g) which does not have
this issue. (side problem: why does JPA insist the discriminator
column be in the primary table and has this been addressed in later
versions? I had to swap CUSTOMERRATING and CUSTOMER to make JPA happy
(arguably, bad legacy table design to begin with).

The configuration follows. The above error occurs for a find() for a
row that maps to GREATCUSTOMER (not VALUEDCUSTOMER, which makes it
even more insteresting).

Hopefully i haven't mangled the example while substituting fake names...

//CLASS 1
@Entity
@Table(name="CUSTOMERRATING")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
// in the real code, pkJoinColumns needed...
@SecondaryTables({
@SecondaryTable(name="CUSTOMER",pkJoinColumns = @PrimaryKeyJoinColumn
        (name="ID"    , referencedColumnName="ID"))
,@SecondaryTable(name="MORECUSTOMERDATA",pkJoinColumns = @PrimaryKeyJoinColumn(
        name="ID" , referencedColumnName="ID"))
@DiscriminatorColumn(name="RATING")
public class Customer extends EntityImpl implements Serializable {
    @Column(name="ID")
    @Id
    protected String id;
    @Column(table="CUSTOMERRATING",name="RATING")
    private String rating;
    @Column(table="CUSTOMER",name="NAME")
    private String name;
//Class 2    
@Entity
@DiscriminatorValue(value="2")
public class ValuedCustomer extends Customer implements Serializable {
    @Column(table="CUSTOMER",name="NAME")
    private String name;}
// Class 3
@Entity
@SecondaryTable(
     name="GREATCUSTOMERDATA"
    ,pkJoinColumns = @PrimaryKeyJoinColumn(
        name="ID"
        , referencedColumnName="ID"))
@DiscriminatorValue(value="9")
public class GreatCustomer extends ValuedCustomer implements Serializable  {
    @Column(table="GREATCUSTOMERDATA",name="ID")
    private String greatCustomerdataId;


      


Mime
View raw message