Программно загружать классы сущностей с помощью JPA 2.0?
С Hibernate вы можете загрузить свои Entity
классы как:
sessionFactory = new AnnotationConfiguration()
.addPackage("test.animals")
.addAnnotatedClass(Flight.class)
.addAnnotatedClass(Sky.class)
.addAnnotatedClass(Person.class)
.addAnnotatedClass(Dog.class);
Есть ли способ сделать то же самое - программно загрузить ваши классы сущностей - в соответствии с JPA 2.0?
Причина этого вопроса в том, что я хотел бы динамически загружать свои Entity
классы, таким образом, не обязательно программно.
3 ответа
С помощью Spring я сделал это в соответствии с JPA.
Мой "persistence.xml" выглядит пустым, без сущностей, перечисленных в <persistence-unit>
элемент.
Затем я написал класс, который реализовал PersistenceUnitPostProcessor следующим образом:
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
public class ReflectionsPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor {
private String reflectionsRoot;
private Logger log = LoggerFactory.getLogger(ReflectionsPersistenceUnitPostProcessor.class);
@Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
Reflections r = new Reflections(this.reflectionsRoot, new TypeAnnotationsScanner());
Set<String> entityClasses = r.getStore().getTypesAnnotatedWith(Entity.class.getName());
Set<String> mappedSuperClasses = r.getStore().getTypesAnnotatedWith(MappedSuperclass.class.getName());
for (String clzz : mappedSuperClasses)
{
pui.addManagedClassName(clzz);
}
for (String clzz : entityClasses)
{
pui.addManagedClassName(clzz);
}
}
public String getReflectionsRoot() {
return reflectionsRoot;
}
public void setReflectionsRoot(String reflectionsRoot) {
this.reflectionsRoot = reflectionsRoot;
}
}
Затем я настроил свой весенний контекст xml следующим образом:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
</bean>
</property>
<property name="persistenceUnitName" value="GenericPersistenceUnit"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="persistenceUnitPostProcessors">
<list>
<bean class="com.austinmichael.core.repository.ReflectionsPersistenceUnitPostProcessor">
<property name="reflectionsRoot" value="com.austinmichael"/>
</bean>
</list>
</property>
</bean>
Обратите внимание на регистрацию ReflectionsPersistenceUnitPostProcessor
в настройке persistenceUnitPostProcessors.
И это все. Каждый класс с сущностью JPA или MappedSuperclass
аннотация на пути к классам добавляется в путь к классам. Я должен был дать отражения префикса имени пакета для сканирования, поэтому com.austinmichael
там вообще. Вы можете зарегистрировать второй ReflectionsPersistenceUnitPostProcessor
с другим префиксом имени пакета, если вы хотите, если ваши сущности не имеют общего префикса имени пакета.
Но теперь это JPNendor агностик.
Есть ли способ сделать то же самое - программно загрузить ваши классы сущностей - в соответствии с JPA 2.0?
Нет, это не поддерживается JPA, поэтому вам придется делать это определенным образом. Джеймс Сазерленд описал процесс для EclipseLink в этой теме следующим образом:
Вы можете получить доступ к EclipseLink
ServerSession
отEntityManagerFactoryImpl
(getServerSession()
), и используйте его 'addDescriptor(ClassDescriptor)
или жеaddDescriptors()
API для добавления EclipseLinkClassDescriptor
, Вам нужно будет построитьClassDescriptor
объекты метаданных напрямую (или используйте Mapping Workbench для их создания), так как загрузка из аннотаций JPA или orm.xml будет более сложной.
Также взгляните на этот более свежий поток, чтобы получить больше примеров кода (API выглядит немного многословно).
Рекомендации
Я не думаю, что есть такая опция - JPA поддерживает сканирование пути к классам для сущностей или явное перечисление классов сущностей в файле persistence.xml. Поскольку вы используете hibernate в качестве поставщика сохраняемости, вы всегда можете прибегнуть к hibernate-коду. Посмотрите на HibernateEntityManager
а также HibernateEntityManagerFactory
классы. Вы можете назначить фабрики менеджеров сущностей и менеджеров сущностей и делать обычные вещи в спящем режиме.