Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] Inheritance and FK relations?

Hi,

At my current client, we have a database with a set of tables for storing invoice information. For some reasons, they have chosen to duplicate the set of tables. After an incoming invoice is paid, it is moved to another table. So we have two identical sets of tables: one for unpaid invoices and one for paid invoices. A simplified version of our database structure is given in the "picture" below.
+---------------+      +---------------+
| UNP_INVOICE | | PAID_INVOICE |
| | | |
| INV_NUMBER | | INV_NUMBER |
| TOTAL_AMOUNT | | TOTAL_AMOUNT |
| ... | | ... |
+---------------+ +---------------+
| |
|fk |fk
+---------------+ +---------------+
| UNP_INV_LINE | | PAID_INV_LINE |
| | | |
| LINE_NUMBER | | LINE_NUMBER |
| DESCRIPTION | | DESCRIPTION |
| AMOUNT | | AMOUNT |
+---------------+ +---------------+


(Note that this is a simplified version. In reality we have 2 times 8 tables with lots of foreign key relations.)

My job is to create a JPA ORM layer on top of this database design, using TopLink 11.1.1. Needless to say that this calls for some smart inheritance. However, I have some difficulties to get things working. My idea was to create an abstract super class for each pair of tables and then create concrete Entity classes for each table, extending the appropriate abstract super class. So I created abstract superclasses with all needed JPA annotations. I annotated the abstract classes as @MappedSuperclass. Then I created the concrete sub classes. The concrete classes are rather minimal, since there are no differences between two concrete classes, apart from the table name. So for the "INVOICE" table, I have three classes:
@MappedSuperclass
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract Invoice{
@Column(name="INV_NUMBER")
private invoiceNumber;
@Column(name="TOTAL_AMOUNT")
private totalAmount;
 
// Accessors go here...
}

@Entity
@Table(name="UNP_INVOICE")
public UnpaidInvoice extends Invoice {
}

@Entity
@Table(name="PAID_INVOICE")
public PaidInvoice extends Invoice {
}

This works as long as there are no foreign key relations between the tables. But when I start adding the relations, the problems start. I added a one-to-many relation to Invoice, as follows:
@MappedSuperclass
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract Invoice{
@Column(name="INV_NUMBER")
private invoiceNumber;
@Column(name="TOTAL_AMOUNT")
private totalAmount;
 
@OneToMany(mappedBy = "invoice", fetch=FetchType.EAGER, cascade={CascadeType.REFRESH, CascadeType.MERGE})
private List<? extends InvoiceLine> invoiceLineList;
 
// Accessors go here...
}

The I tried overriding the relation in the concrete classes:
@Entity
@Table(name="UNP_INVOICE")
@AssociationOverride(name = "invoiceLineList", joinColumns = @JoinColumn(table = "UNP_INV_LINE"))
public UnpaidInvoice extends Invoice {
}

When I deploy this to WebLogic, the WL deployer says:
[wldeploy] Local Exception Stack:
[wldeploy] Exception [EclipseLink-7250] (Eclipse Persistence Services - 1.2.0.v20091016-r5565): org.eclipse.persistence.exceptions.ValidationException
[wldeploy] Exception Description: [package.UnpaidInvoice] uses a non-entity [package.InvoiceLine] as target entity in the relationship attribute [field invoiceLineList].


A solution I can think of is to not declare the relationships in the super class. But that means I'll have to duplicate the declaration of the relationship in the concrete classes. Another solution I thought of was making the abstract classes @Entity instead of @MappedSuperclass. But then the @AssociationOverride does not work, and Toplink will search the database for a table called "INVOICELINE", but that does not exist.

Does anyone know of a smarter solution to this problem? Thanks in advance!

Best regards,
Bart Kummel

Back to the top