JPA, как использовать один и тот же класс (сущность) для сопоставления разных таблиц? - PullRequest
40 голосов
/ 15 июня 2009

У меня есть две таблицы: Ta и Tb. У них точно такая же структура таблицы, но разные имена таблиц.

Я пытаюсь создать один класс сущностей для сопоставления структур таблиц. Некоторые из моих общих прикладных модулей будут использовать этот класс сущностей для динамического запроса и обновления либо Ta, либо Tb на основе параметров. Это можно сделать в JPA? Как я могу написать программу для динамического отображения класса сущностей в разные таблицы во время выполнения?

Ответы [ 3 ]

44 голосов
/ 15 июня 2009

Не уверен, что вы можете сделать это именно так, как вы хотите, но вы можете использовать наследование для получения того же результата.

В AbsT есть все поля, но нет аннотации @Table

Ta и Tb наследуются от AbsT и имеют аннотацию @Table каждый

Использование

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

в абс.

Пример кода:

@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 {
...
}
21 голосов
/ 15 октября 2010

Создайте абстрактный класс (шаблонный класс) с аннотацией @MappedSuperclass, а затем расширьте его. Каждый расширяемый класс использует аннотации @table, @entity и не содержит ничего, кроме пустого конструктора. Весь код будет в вашем родительском классе. В ваших методах используйте обобщенные значения, указывающие на то, что ваша сущность параметра простирается от templateClass, и больше никаких изменений кода не требуется. Надлежащие отображения будут в каждом сыне, которого вы проходите.

7 голосов
/ 29 июня 2009

Вы также можете сделать это без использования подклассов, если вы используете две разные единицы персистентности.

Каждая единица персистентности может указывать уникальный набор отображений (включая имя таблицы). Один из способов добиться этого - создать два файла orm.xml. В файле persistence.xml вам понадобится что-то вроде этого:

<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>

Тогда в 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>

И в 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>

Вам нужно будет создать отдельную EntityManagerFactory для каждого PersistenceUnit (возможно, не того, что вы хотите), но если вы хотите использовать один и тот же класс в разных базах данных (с разными именами таблиц), это будет путь.

...