EntityManager ที่ฉีดเข้ามาไม่รู้จักเอนทิตี

ฉันมีแอปพลิเคชัน Java EE พื้นฐานที่กำหนดไว้ใน Eclipse (หนึ่ง EJB, หนึ่งหน้าเว็บที่มี PrimeFaces, หนึ่งเอนทิตี JPA) มีสี่โปรเจ็กต์ หนึ่งโปรเจ็กต์สำหรับ EAR หนึ่งโปรเจ็กต์สำหรับ EJB หนึ่งโปรเจ็กต์สำหรับ JPA และอีกหนึ่งโปรเจ็กต์สำหรับ web part ปัญหาคือฉันพยายามกำหนดค่า Hibernate เป็นเฟรมเวิร์กการคงอยู่ใน Persistence.xml ในโครงการ JPA และมันไม่ทำงานอย่างสมบูรณ์อย่างที่ฉันคาดหวัง ใน EJB ของฉัน (@Stateless) ฉันสามารถดึงข้อมูล EntityManager ได้สองวิธี ฉันสามารถดึงข้อมูลได้ผ่านทาง Persistence.createEntityManagerFactory() ... entertManagerFactory.createEntityManager() และฉันสามารถดึงข้อมูลได้ผ่านทางคำอธิบายประกอบ @PersistenceContext(unitName = "") อย่างไรก็ตาม เฉพาะคลาส Entity ของฉัน (ที่มีคำอธิบายประกอบด้วย @Entity) เท่านั้นที่จะได้รับการยอมรับเมื่อฉันทำการสืบค้น

รหัสนี้ใช้งานได้ เอนทิตี "ประเทศ" เป็นที่รู้จักของ (Hibernate) EntityManager ที่ฉันได้รับ:

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

แต่การใช้คำอธิบายประกอบในคลาสเดียวกันจะไม่ทำงาน (มีข้อยกเว้นเกิดขึ้น ดูด้านล่าง):

@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);

ในบรรทัดสุดท้ายมีข้อยกเว้นว่าคลาส "Country" ไม่ใช่ "Entity" เมื่อตรวจสอบ EntityManager ที่ถูกฉีดเข้าไป ฉันสามารถเห็นประเทศในเซสชันและบริบทการคงอยู่ แต่ดูเหมือนว่าจะไม่ทราบ นี่คือข้อยกเว้นที่เกิดขึ้น:

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

ฉันได้รวมขวด Hibernate ไว้ในไฟล์ EAR เป็น "ไลบรารีที่รวมกลุ่ม" และฉันได้ลองเพิ่มลงในโฟลเดอร์ "lib" ของ Glassfish ด้วย เนื่องจาก Hibernate ทำงานร่วมกับการใช้งานครั้งแรกด้านบน ฉันจึงถือว่ามีการกำหนดค่าอย่างถูกต้องด้วยขวดที่ถูกต้อง

Persistence.xml ของฉันมีลักษณะเช่นนี้ (และอยู่ในโครงการ JPA ภายใต้ META-INF และเป็นส่วนหนึ่งของ 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>

สำหรับการอ้างอิง: Hibernate v4.3.6, EJB v3.2, Glassfish v4.1, JPA v2.1

ใครช่วยบอกเบาะแสให้ฉันหน่อยได้ไหมว่าฉันขาดอะไรไป? จำเป็นต้องมีการกำหนดค่าเพิ่มเติมหรือไม่? ฉันจะบอกใบสมัครได้อย่างไรว่านิติบุคคลของประเทศอยู่ที่ไหน

ฉันคิดว่าการเพิ่ม @Entity ให้กับเอนทิตีจะต้องมีการลงทะเบียน (สิ่งนี้จะเกิดขึ้นเมื่อฉันเรียก Persistence.createEntityManagerFactory(...) อย่างไรก็ตาม ไม่ใช่เมื่อ EntityManager หรือ EntityManagerFactory ถูกฉีดผ่าน Java EE/Glassfish ฉันได้ลองเพิ่มด้วย คลาสที่มี ... ถึง Peristence.xml ไม่มีประโยชน์ เมื่อฉันตรวจสอบ EntityManager ที่ถูกฉีดเข้าไป ฉันสามารถค้นหาคลาส Country ในบริบทการคงอยู่ได้ ดังนั้นจึงได้รับการลงทะเบียนด้วยแล้ว แต่ยังไม่สามารถใช้คลาสในแบบสอบถามได้ .


person Raoul    schedule 06.10.2014    source แหล่งที่มา
comment
หากฉันฉีด EntityManagerFactory ผ่านทางคำอธิบายประกอบ PersistenceUnit(unit-name=‹unit-name›) ฉันจะได้รับการใช้งาน Hibernate แต่การใช้งานนี้ดูเหมือนจะไม่ทราบเกี่ยวกับเอนทิตีประเทศของฉัน จะมีการใช้งาน Hibernate สองแบบได้อย่างไร แบบหนึ่งที่รู้จักเอนทิตี และอีกแบบหนึ่งที่ไม่รู้จักเอนทิตี ??? สันนิษฐานว่าคำอธิบายประกอบ PersistenceContext ทำให้คุณใช้งาน Glassfish ได้อย่างคงอยู่ ในขณะที่การใช้ PersistenceUnit คุณจะได้รับการใช้งาน PersistenceUnit ของแอปพลิเคชันของคุณเอง หรืออย่างน้อยฉันคิดว่าฉันอ่านเจอที่ไหนสักแห่ง...   -  person Raoul    schedule 06.10.2014
comment
ด้วย EntityManager ใดๆ ไม่ว่าจะฉีดเข้าไปหรือไม่ก็ตาม สิ่งนี้จะได้ผล ดูเหมือนว่าการฉีดกำลังทำงานอยู่ และวัตถุนั้นได้รับการยอมรับและพร้อมใช้งานสำหรับไฮเบอร์เนต แต่สำหรับ EntityManagers ที่ฉีดเข้าไป ดูเหมือนจะไม่สามารถใช้งานได้โดยใช้ชื่อคลาส หรืออย่างน้อยนั่นคือสิ่งที่ตอนนี้ดูเหมือน... Final Query query = this.entityManager.createQuery(SELECT c FROM Country c); รายการสุดท้าย resultList = query.getResultList();   -  person Raoul    schedule 06.10.2014
comment
ปัญหาเกิดขึ้นที่นี่: ลิงก์   -  person Raoul    schedule 08.10.2014


คำตอบ (1)


ตกลง ดูเหมือนว่าปัญหาจะเกี่ยวข้องกับความจริงที่ว่าฉันมีคลาส Entity สองอินสแตนซ์ สิ่งนี้อธิบายว่าทำไมฉันจึงสามารถสืบค้นโดยใช้ภาษาคิวรี แต่ไม่สามารถใช้คลาส Entity ได้ ฉันได้ติดตามโค้ดไปที่ MetamodelImpl ที่ดูในแมปของเอนทิตี แต่เนื่องจากคลาสที่ลงทะเบียนไว้ (อย่างถูกต้อง) ไม่เหมือนกับคลาสที่ใช้ใน CriteriaQuery.from() ฉันค้นหาคลาสหลายอินสแตนซ์ในโฟลเดอร์ที่มีการปรับใช้แอปพลิเคชัน Java EE แต่ฉันไม่พบคลาสหลายอินสแตนซ์ ดังนั้นอาจเกี่ยวข้องกับการโหลดคลาสและ/หรือความจริงที่ว่าแอปพลิเคชันมีหลายโปรเจ็กต์ย่อย (jpa, web, ejb) แต่ละอันอ้างอิงถึงคลาส Entity หรืออาจเนื่องมาจาก Eclipse ไม่ว่าจะด้วยวิธีการใช้งานหรือวิธีการสร้างแยกกัน อะไหล่...

ไม่ว่าในกรณีใด ดูเหมือนว่าปัญหาจะไม่ใช่หนึ่งใน JPA, Hibernate, EJB ฯลฯ

person Raoul    schedule 07.10.2014