Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA entity mapping to optional SecondaryTable

I have an entity. I would like to optionally load additional information about the entity from a secondary table. I have the following mapping.

@Entity
@Table( name = "program", schema = "myschema" )
@SecondaryTable( name = "program_info", schema = "myschema", pkJoinColumns =
        @PrimaryKeyJoinColumn( name = "program_id", referencedColumnName = "program_id" ) )
public class Program { ... }

I have all the columns mapped appropriately, and a unit test that works. The trouble comes when I have a row in the program table that does not have a corresponding row in the program_info table. In that case it won't load the program at all. I need to be able to mark the entire secondary table as optional. I would prefer to stay away from having to create another entity/dao/service and do a 1-1 mapping.

I'm using eclipselink but would like to stay away from provider specific details if I can.

like image 382
digitaljoel Avatar asked Nov 10 '10 17:11

digitaljoel


People also ask

How do you make a field optional in a JPA entity?

You can define additional constructor for the User entity: @Entity @Table(name="USER") public class User { public User(){ } public User(Integer id, String name){ this.id = id; this.name = name; } // ... } and then write the following query: @Query("select new your.

How do you map an entity to multiple tables?

Yes, you can map an entity to 2 database tables in 2 simple steps: You need to annotate your entity with JPA's @Table and @SecondaryTable annotations and provide the names of the first and second table as the value of the name parameters.

How do you map entity to a table?

In Spring Data JPA we can map an entity to a specific table by using @Table annotation where we can specify schema and name. But Spring Data JDBC uses a NamingStrategy to map an entity to a table name by converting the entities class name.

What is @basic optional false?

It means, if you try to persist an entity with a null field it will throw an exception if it is marked as optional=false (without contacting the database) and the entity will not be added to the JPA persistence context.


1 Answers

I need to be able to mark the entire secondary table as optional.

EclipseLink will perform an INNER JOIN with a SecondaryTable so if there is no corresponding row in the secondary table, you'll get nothing. In other words EL expects to find a row in the secondary table (when creating, reading, updating, deleting).

If what you want is an OUTER JOIN, you should use an optional OneToOne association (maybe with a shared primary key in your case).

An alternative would be to use a database view (doing an OUTER JOIN) and to map the view.

I would prefer to stay away from having to create another entity/dao/service and do a 1-1 mapping.

I don't see why having an optional OneToOne forces you to have a corresponding DAO and service. Manage the optional part through the main "holder" part.

See also

  • JPA Wiki book
    • Multiple table outer joins
like image 156
Pascal Thivent Avatar answered Sep 19 '22 11:09

Pascal Thivent