60

I have two tables: Ta and Tb. They have exactly the same table structure but different table names.

I try to create one entity class to map the table structures. Some of my common application modules will use this entity class to dynamically query and update either Ta or Tb based on parameters. Can it be done in JPA? How can I write the program to dynamically mapping the entity class to different tables at run time?

huzeyfe
  • 3,554
  • 6
  • 39
  • 49

3 Answers3

55

Not sure you can do it exactly as you want but you can use inheritance to produce the same result.

AbsT has all the fields but no @Table annotation

Ta and Tb inherit from AbsT and have an @Table annotation each

Use

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

in AbsT.

Sample code:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class abstract AbsT {
    @Id Long id;
...
}

@Entity
@Table(name = "Ta")
public class Ta extends AbsT {
...
}

@Entity
@Table(name = "Tb")
public class Tb extends AbsT {
...
}
Michael Piefel
  • 18,660
  • 9
  • 81
  • 112
Glen
  • 21,816
  • 3
  • 61
  • 76
  • 9
    It does work, Thanks! However, for Toplink, TABLE_PER_CLASS is not supported. I tried @mappedSuperClass method and it works as well. –  Jun 16 '09 at 15:01
  • 6
    For whoever is uncertain about Inheritance vs MappedSuperClass, they are described and compared very well here: http://stackoverflow.com/a/9669719/2278186 – SatA May 20 '14 at 10:08
  • my tables names are different and columns are of same type but different names , for example country column in one table is named domicile in the other. column contains countries but column name is slightly different, how to alter this example to cater my case , any idea ? – Sithija Piyuman Thewa Hettige Jun 01 '23 at 06:04
28

Create an abstract class (a template class) with annotation @MappedSuperclass then extend it. Each class that extends uses @table, @entity annotations and contains nothing but an empty constructor. All code will be in your parent class. On your methods use generics indicating your parameter entity extends from templateClass and no more code changes are needed. The proper mappings will be in each son you pass.

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
arbano
  • 281
  • 3
  • 2
8

You can also do this without using subclasses if you use two different persistence units.

Each persistence unit can specify a unique set of mappings (including table name). One way to achieve this is to create two orm.xml files. In persistence.xml you'll need something like this :

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="1.0">

    <persistence-unit name="mapping-1"> 
        . . .
        <mapping-file>orm-1.xml</mapping-file>
        . . .
    </persistence-unit>

    <persistence-unit name="mapping-2"> 
        . . .
        <mapping-file>orm-2.xml</mapping-file>
        . . .
    </persistence-unit>
</persistence>

Then within orm-1.xml :

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
    version="1.0">
    <package>mypackage</package>
    <entity name="myEntity" class="myClass">
        <table name="TABLE1">
            </table>
    </entity>
</entity-mappings>

And within orm-2.xml :

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
    version="1.0">
    <package>mypackage</package>
    <entity name="myEntity" class="myClass">
        <table name="TABLE2">
            </table>
    </entity>
</entity-mappings>

You'll need to create a separate EntityManagerFactory for each PersistenceUnit (probably not what you want), but if you wanted to use the same class on different databases (with different table names) this would be a way to go.

Mike
  • 18,694
  • 1
  • 20
  • 10