2015-01-11 64 views
0

我一直在使用Guice實現一個模塊化架構應用程序,每個應用程序模塊分爲單獨的eclipse項目並擁有自己的Guice模塊。我在註冊JPA實體時遇到了問題,這些實體不在JPA持久性項目中。項目內部的註冊沒有問題,但其他項目中的不是。應用程序在單個項目和單個Guice模塊上實現時沒有問題。JPA Entity未註冊EntityManager

配置看起來沒問題,但最有可能是我缺少的東西。 這是錯誤試圖從數據庫中獲取的實體時,我得到:

Caused by: java.lang.IllegalArgumentException: Not an entity: class org.gradle.security.persistence.jpa.entities.impl.SubjectImpl 
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 org.gradle.security.pbeingersistence.jpa.dao.impl.SubjectDAOImpl.findByPrincipal(SubjectDAOImpl.java:48) 

與下面的SubjectDAOImpl並試圖獲得最後一行的實體時出錯,

public Subject findByPrincipal(String principal, LockModeType lockMode) { 
    CriteriaQuery<SubjectImpl> criteria = criteriaQuery(SubjectImpl.class); 
    CriteriaBuilder cb = getEM().getCriteriaBuilder(); 

    Root<SubjectImpl> activation = criteria.from(SubjectImpl.class); 
    .... 

與SubjectImpl是:

@Entity 
@Audited 
@Table(name=SubjectImpl.TABLE_NAME, schema=Config.Schemas.DEFAULT) 
public class SubjectImpl extends BaseEntityImpl implements Subject { 

    public static final String TABLE_NAME = Config.TABLE_PREFIX + "subject"; 

    @Basic(optional = false) 
    @Column(name = "principal", unique = true) 
    protected String principal; 
    ...... 
} 

的吉斯模塊被配置如下:

安全模塊:

private static class SecurityModule extends AbstractModule { 

    @Override 
    protected void configure() { 
     bind(Subject.class).to(SubjectImpl.class).asEagerSingleton(); 
     ... 
     bind(SubjectDAO.class).to(SubjectDAOImpl.class).asEagerSingleton(); 
    } 

} 

持久性模塊:

public class JPAPersistenceModule extends AbstractModule implements ArchetypeModule { 
    @Override 
    protected void configure() { 
     try { 
     Properties props = new Properties(); 
     InputStream is = new FileInputStream(
       this.getClass().getClassLoader().getResource(PersistenceProperties.DEFAULT_PROPERTIES_FILE).getPath()); 
     props.load(is); 
     Names.bindProperties(binder(), props); 

     bind(PersistenceProperties.class).asEagerSingleton(); 
     JpaPersistModule persistModule = new JpaPersistModule(PersistenceProperties.PERSISTENCE_UNIT); 
     persistModule.properties(props); 
     install(persistModule); 
    } catch (IOException e) { 
     LOGGER.error("Could not load persistence module: ", e); 
     System.exit(-1); 
    } 
} 

而服務器模塊:

public class ServerModule extends JerseyServletModule implements ArchetypeModule { 
    @Override 
    protected void configureServlets() { 
     filter("/*").through(PersistFilter.class); 
     serve("/rest","/rest/*").with(GuiceContainer.class); 
    } 
} 

的吉斯模塊由該順序安裝:JPAPersistenceModule,SecurityModule,ServerModule。 無法解決問題,你能幫我一把嗎?

+0

爲什麼不從工作示例開始? – SkorpEN

+0

您是否在引用Guice JPA工作示例?剛纔注意到,由於Guice模塊,我使用的「多模塊」這個詞有點令人困惑。我正在實現一個模塊化的應用程序體系結構,其中每個guice模塊都在其獨立的eclipse項目中。我會編輯,避免混淆。雖然在單個項目和單個guice模塊上,一切都像魅力一樣。 –

回答

0

在與使用相同架構和類似技術實現項目的朋友交談之後,我發現原因是由於JPA Hibernate限制造成的。與許多其他註釋不同,JPA實現的註釋只能在實現Guice持久性模塊的項目上檢測到。

解決此問題的方法是使用反射捕獲所有具有註釋的類(Reflections庫爲您執行此操作),並將其傳遞給屬性參數上的Guice JpaPersistModule。 結果應該與此有些類似:

props.put(org.hibernate.jpa.AvailableSettings.LOADED_CLASSES, Lists.newArrayList(EntityLoader.loadEntities())); 

JpaPersistModule persistModule = new JpaPersistModule(PersistenceProperties.PERSISTENCE_UNIT); 
persistModule.properties(props); 
install(persistModule);