我有一個Persistence.xml存在多個持久性單元定義文件。相對持久單元注入?
我想根據進入系統的用戶注入單元EntityManager對象。
可能嗎?
@PersistenceContext (unitName = myUnit)
在此使用,我得到一個警告: 「屬性值必須是常量」
應用框架:JSF 2.1 &春3.0.2
持久層:JPA
我有一個Persistence.xml存在多個持久性單元定義文件。相對持久單元注入?
我想根據進入系統的用戶注入單元EntityManager對象。
可能嗎?
@PersistenceContext (unitName = myUnit)
在此使用,我得到一個警告: 「屬性值必須是常量」
應用框架:JSF 2.1 &春3.0.2
持久層:JPA
由於錯誤消息說,Java註釋屬性必須是常量值,而不是對變量的引用。這是Java語言中的一個限制,而不是JPA。你需要找到一種不同的方式去做你想做的事情。
正如在另一篇文章中提到的,註釋屬性必須是常量。
另一種方法可以編程得到一個EntityManager實例:
Persistence.getEntityManagerFactory().getEntityManager(persistenceUnitName);
您可以實現分配取決於你自己的標準持久性單元名稱所必需的邏輯。顯然,這與持久性不再由容器管理的事實相關。
你可以使用CDI嗎?你可以編寫一個小類,它被注入所有不同的上下文,然後通過一個生成器方法將它們提供給你的類,它會執行一些邏輯。喜歡該位:
public class PersistenceContext {
@PersistenceContext(unitName="myUnit") private EntityManager myEm;
@PersistenceContext(unitName="yourUnit") private EntityManager yourEm;
@Produces
public EntityManager getEntityManager(InjectionPoint ip) {
if (USER IS ME) {
return myEm;
}
else if (USER IS YOU) {
return yourEm;
}
else {
NOW PANIC AND FREAK OUT
}
}
}
然後,你可以只寫類是這樣的:
public class FeedReamer {
@Inject private EntityManager em;
}
一切都會神奇地出現權(可能?)。
如果你不想硬編碼持久化單元的名稱中的類,然後的而不是依靠注射,你可以明確地得到實體管理器工廠:
@Produces
public EntityManager getEntityManager(InjectionPoint ip) {
String persistenceUnitName = somehowDeterminePersistenceUnitName();
EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);
return emf.createEntityManager();
}
然而,雖然這種方法可以在J2SE應用程序中工作,但不保證Persistence.createEntityManagerFactory能夠在J2EE中工作。腳註42的規格(在EJB 3.0規範的持久性,至少)說:
這些Java SE自舉的API的使用可以用Java EE容器的支持;然而,不需要支持這種使用。
此外,我認爲創建一個新的EntityManagerFactory可能會很慢;您可能會發現需要緩存查找結果。我相信應該很長時間堅持一個EntityManagerFactory,並從多個線程訪問它(但我不確定)。
我認爲這是正確的方向。儘管如此,我不確定Spring是否會自帶實現'@Inject'和其他註釋。不知道它將如何合作... –
啊,我錯過了你使用春天,對不起。我相信Spring有它自己的@Produces的等價物 - 你應該可以使用它來實現相同的模式。 –
嗨湯姆安德森。 建議的方法,當有固定數量的單位可用時。 我的系統上的單元數目不穩定,可隨時增加,而且我不想幹擾java。 – hakdogan
我達成了解決方案。我是Spring的新人。確實有更好的解決方案,但我仍然想分享解決方案。
的applicationContext.xml
<context:component-scan base-package="com.hakdogan.hakdoganjsfspring"/
<tx:annotation-driven transaction-manager="transactionManagerConstant"/
<tx:annotation-driven transaction-manager="transactionManagerRelative"/
<bean id="odev" class="com.hakdogan.hakdoganjsfspring.entity.Nesne"/
<bean id="transactionManagerConstant"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="constant"/>
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="transactionManagerRelative"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="relative"/>
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaDialect"
class="com.hakdogan.hakdoganjsfspring.util.HibernateExtendedJpaDialect"/
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitMa nager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
<value>classpath*:META-INF/hk.xml</value>
</list>
</property>
</bean>
<bean id="constant"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager"
ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="JSFSpring" />
</bean>
<bean id="relative"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager"
ref="persistenceUnitManager" />
</bean>
<bean id="persistenceManager"
class="com.hakdogan.hakdoganjsfspring.util.PersistenceManager"/>
</beans>
PersistenceManager.java
public class PersistenceManager {
private LocalContainerEntityManagerFactoryBean persistence;
public LocalContainerEntityManagerFactoryBean getPersistence() {
return persistence;
}
@Autowired
@Qualifier("relative")
public void setPersistence(LocalContainerEntityManagerFactoryBean
persistence) {
this.persistence = persistence;
}
}
PersistDAO.java
@Component("persistDAO")
@Scope("session")
public class PersistDAO {
@PersistenceContext(unitName="JSFSpring")
private EntityManager em;
@Autowired
private PersistenceManager persistenceManager;
@Autowired
private Nesne nesne;
private List<Odev> kayitListesi;
private List<Event> eventListesi;
private String myUnit = "hakdogan";
public Nesne getNesne() {
return nesne;
}
public void setNesne(Nesne nesne) {
this.nesne = nesne;
}
@Transactional(isolation = Isolation.SERIALIZABLE, propagation =
Propagation.REQUIRED)
public String kaydet(){
em.persist(nesne);
return "/liste.xhtml";
}
@Transactional(propagation = Propagation.REQUIRED, readOnly=true)
public List<Odev> getKayitListesi() {
return kayitListesi = (List<Odev>)
em.createNamedQuery("Odev.findAll").getResultList();
}
@Transactional(readOnly=true)
public List<Event> getEventListesi() {
persistenceManager.getPersistence().setPersistenceUnitName(myUnit);
EntityManager emt = persistenceManager.getPersistence().getNativeEntityManagerFactory().createEntityManager();
return eventListesi = (List<Event>)
emt.createNamedQuery("Event.findAll").getResultList();
}
}
我的解決方案是解決不了問題:)
的applicationContext.xml :
<context:component-scan base-package="com.hakdogan.hakdoganjsfspring"/>
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManagerConstant"/>
<tx:annotation-driven transaction-manager="transactionManagerRelative"/>
<bean id="jpaDialect" class="com.hakdogan.hakdoganjsfspring.util.HibernateExtendedJpaDialect" />
<bean id="transactionManagerConstant" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="constant"/>
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="transactionManagerRelative" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="relative"/>
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="constant" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="persistenceUnitName" value="JSFSpring" />
</bean>
<bean id="relative" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="persistenceUnitName" value="hakdogan" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</bean>
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
</bean>
<bean id="persistenceManager" class="com.hakdogan.hakdoganjsfspring.util.PersistenceManager"/>
<bean id="odev" class="com.hakdogan.hakdoganjsfspring.entity.Odev" scope="prototype" />
</beans>
PersistenceManager.java:
public class PersistenceManager {
@Autowired
private LocalEntityManagerFactoryBean persistence;
private PersistenceProvider provider;
public EntityManager getBaglam(String unitName){
if(null == provider)
provider = persistence.getPersistenceProvider();
if(!unitName.equals(persistence.getPersistenceUnitName()))
persistence.setPersistenceUnitName(unitName);
return provider.createEntityManagerFactory(unitName, null).createEntityManager();
}
}
PersistDAO.java:
@Component("persistDAO")
@Scope("session")
public class PersistDAO {
@PersistenceContext(unitName="JSFSpring")
private EntityManager em;
@Autowired
private PersistenceManager persistenceManager;
private List<Odev> kayitListesi;
private List<Event> eventListesi;
private List<Musteriler> musteriListesi;
private String myUnit = "hakdogan";
@Transactional(propagation = Propagation.REQUIRED, readOnly=true)
public List<Odev> getKayitListesi() {
return kayitListesi = (List<Odev>) em.createNamedQuery("Odev.findAll").getResultList();
}
@Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED)
public List<Event> getEventListesi() {
return persistenceManager.getBaglam(myUnit).createQuery("SELECT e FROM Event e").getResultList();
}
@Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRED)
public List<Musteriler> getMusteriListesi() {
return persistenceManager.getBaglam("musteri").createNamedQuery("Musteriler.findAll").getResultList();
}
}
不具有的特性,如LocalEntityManagerFactoryBean負責persistenceUnitManager。出於這個原因,我無法設置單位的名稱。
代價是創建EntityManagerFactory發生。試圖減慢項目。
我正在尋找一種有效的解決方案。
謝謝。
最終變量無法找出這個問題。 你能建議我一個不同的可以找到? – hakdogan
最終變量!=常數 – skaffman
我想說 private String unit =「myUnit」; private final String unitNanme = unit; @PersistenceContext(unitName = unitNanme) private EntityManager em; – hakdogan