Saya memiliki aplikasi Java EE yang sangat mendasar yang ditentukan di Eclipse (satu EJB, satu halaman web dengan PrimeFaces, satu entitas JPA). Ini memiliki empat proyek, satu untuk EAR, satu untuk EJB, satu untuk JPA dan satu untuk komponen web. Masalahnya adalah saya telah mencoba mengkonfigurasi Hibernate sebagai kerangka persistensi di persistence.xml di proyek JPA, dan itu tidak sepenuhnya berfungsi seperti yang saya harapkan. Di EJB saya (@Stateless) saya dapat mengambil EntityManager dengan dua cara. Saya dapat mengambilnya melalui Persistence.createEntityManagerFactory() ... entitasManagerFactory.createEntityManager(), dan saya dapat mengambilnya melalui anotasi @PersistenceContext(unitName = "") . Namun, hanya dengan yang pertama kelas Entitas saya (dijelaskan dengan @Entity) dikenali ketika saya melakukan kueri.
Kode ini berfungsi, entitas "Negara" diketahui oleh EntityManager (Hibernate) yang saya dapatkan:
final EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("<unit-name>");
final EntityManager entityManager = entityManagerFactory.createEntityManager();
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Country> criteriaQuery = criteriaBuilder.createQuery(Country.class);
final Root<Country> root = criteriaQuery.from(Country.class);
tetapi menggunakan anotasi di kelas yang sama ini tidak berhasil (pengecualian diberikan, lihat di bawah):
@PersistenceContext(unitName = "<unit-name>")
private EntityManager entityManager;
...
final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
final CriteriaQuery<Country> criteriaQuery = criteriaBuilder.createQuery(Country.class);
final Root<Country> root = criteriaQuery.from(Country.class);
Pada baris terakhir, pengecualian diberikan bahwa kelas "Negara" bukan "Entitas". Setelah memeriksa EntityManager yang disuntikkan, saya dapat melihat Negara dalam sesi dan konteks persistensi, namun sepertinya negara tersebut tidak mengetahuinya. Inilah pengecualian yang dilempar:
2014-10-06T16:06:29.634+0200|Severe: java.lang.IllegalArgumentException: Not an entity: class <package>.entity.Country
at org.hibernate.jpa.internal.metamodel.MetamodelImpl.entity(MetamodelImpl.java:203)
at org.hibernate.jpa.criteria.QueryStructure.from(QueryStructure.java:139)
at org.hibernate.jpa.criteria.CriteriaQueryImpl.from(CriteriaQueryImpl.java:173)
at <package>.CountrySessionBean.getCountries(CountrySessionBean.java:35)
...
Saya telah memasukkan toples Hibernate ke dalam file EAR sebagai "perpustakaan yang dibundel", dan saya juga mencoba menambahkannya ke folder "lib" di Glassfish. Karena Hibernate bekerja dengan implementasi pertama di atas, saya berasumsi Hibernate dikonfigurasi dengan benar dengan toples yang benar.
Persistensi.xml saya terlihat seperti ini (dan berada dalam proyek JPA di bawah META-INF, dan pada gilirannya merupakan bagian dari EAR):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="<unit-name>" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>MySQLResource</jta-data-source> <!-- DEFINED IN GLASSFISH -->
<properties>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.SunONETransactionManagerLookup" /> <!-- NEEDED? -->
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
...
</properties>
</persistence-unit>
</persistence>
Untuk referensi: Hibernate v4.3.6, EJB v3.2, Glassfish v4.1, JPA v2.1.
Adakah yang bisa memberi saya petunjuk apa yang saya lewatkan? Apakah diperlukan konfigurasi tambahan? Bagaimana cara memberi tahu aplikasi di mana entitas Negara berada?
Saya pikir menambahkan @Entity ke entitas akan membuatnya terdaftar (ini dilakukan ketika saya memanggil Persistence.createEntityManagerFactory(...), namun, tidak ketika EntityManager atau EntityManagerFactory disuntikkan melalui Java EE/Glassfish. Saya juga mencoba menambahkan kelas dengan ... ke persistence.xml tidak berhasil. Ketika saya memeriksa EntityManager yang disuntikkan, saya dapat menemukan kelas Negara dalam konteks persistensinya, sehingga TELAH terdaftar di dalamnya, namun saya tidak dapat menggunakan kelas tersebut dalam kueri .