Автор оригинала: Vlad Mihalcea.
Флемминг Хармс задал очень хороший вопрос в Твиттере:
Есть ли способ, чтобы файл #JPA отображался вне файла jar. Ищете решение для изменения файла t без обновления файла jar/| #spring
В принципе, мы хотим переместить XML-сопоставления JPA за пределы JAR-файла приложения, чтобы мы могли изменить сопоставление, не затрагивая файл jar.
В спецификации JPA довольно четко указано местоположение соответствующего persistence.xml
и файлы сопоставления XML (например, orm.xml
):
XML-файл объектно-реляционного сопоставления с именем orm.xml
может быть указан в каталоге META-INF
в корневом каталоге модуля сохранения или в каталоге META-INF
любого файла jar, на который ссылается persistence.xml
.
В качестве альтернативы или в дополнение, на один или несколько файлов сопоставления могут ссылаться элементы файл сопоставления
элемента единицы сохранения. Эти файлы сопоставления могут присутствовать в любом месте пути к классу.
Таким образом, файлы XML-сопоставлений должны располагаться в пути к классам, чтобы Загрузчик классов
мог загружать их в качестве ресурсов.
Таким образом, XML-сопоставления могут быть расположены за пределами файла JAR, но содержащая его папка должна быть включена в путь к классу Java .
При использовании Hibernate вам даже не нужно включать папку сопоставления XML в путь к классам Java, потому что Hibernate может разрешить любой допустимый файл сопоставления
URL.
Поэтому наш persistence.xml
сопоставления выглядят следующим образом:
org.hibernate.jpa.HibernatePersistenceProvider file:///D:/Vlad/Work/Examples/mappings/orm.xml
Файл сопоставления
может принимать любой URL-адрес. В этом конкретном примере папка сопоставления
расположена за пределами каталога, в котором находится код приложения.
Учитывая, что у нас есть следующий Пост
объект:
public class Post { private Long id; private String title; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
и связанные с ним orm.xml
файл сопоставления:
При выполнении следующего тестового случая:
public class PostTest { protected final Logger LOGGER = LoggerFactory.getLogger( getClass()); private EntityManagerFactory entityManagerFactory; @Before public void setup() { entityManagerFactory = Persistence .createEntityManagerFactory( "externalMapping"); } @After public void tearDown() { if ( entityManagerFactory != null && entityManagerFactory.isOpen()) { entityManagerFactory.close(); } } public EntityManagerFactory getEntityManagerFactory() { return entityManagerFactory; } @Test public void HHH10385Test() throws Exception { doInJPA( this::getEntityManagerFactory, entityManager -> { Post post = new Post(); post.setId(1L); post.setTitle("High-Performance Java Persistence"); entityManager.persist(post); }); doInJPA( this::getEntityManagerFactory, entityManager -> { Post post = entityManager.find(Post.class, 1L); LOGGER.debug("Fetched post: {}", post.getTitle()); }); } }
Получается следующий результат:
INSERT INTO Post (title , id) VALUES ('High-Performance Java Persistence', 1) SELECT p.id as id1_1_0_, p.title as title2_1_0_ FROM Post p WHERE p.id = 1 -- Fetched post: High-Performance Java Persistence
Отлично!
В то время как JPA требует, чтобы сопоставления XML-файлов были расположены в пути к классам Java, Hibernate позволяет хранить сопоставления XML-файлов везде, где вы хотите. Пока файл сопоставления
URL доступен, все будет в порядке.