Относительная стойкость единицы залить? - PullRequest
3 голосов
/ 27 ноября 2011

У меня есть файл Persistence.xml с несколькими определениями модулей постоянства.

Я хочу ввести объект EntityManager, в соответствии с пользователем, который вошел в систему.

Возможно ли это?

@PersistenceContext (unitName = myUnit)

В этом случае я получаю предупреждение: «значение атрибута должно быть постоянным»

Фреймворки приложений: JSF 2.1 и Spring 3.0.2

Постоянный слой: JPA

Ответы [ 5 ]

2 голосов
/ 28 ноября 2011

Можете ли вы использовать 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) гласит:

Использование этих API начальной загрузки Java SE может поддерживаться в контейнерах Java EE;однако поддержка такого использования не требуется.

Кроме того, я считаю, что создание нового EntityManagerFactory может быть довольно медленным;Вы можете найти, что вам нужно кэшировать результаты поиска.Я полагаю, что можно безопасно удерживать EntityManagerFactory в течение длительного времени и получать к нему доступ из нескольких потоков (но я не уверен).

1 голос
/ 28 ноября 2011

Как уже упоминалось в другом посте, атрибуты аннотации должны быть постоянными.

Другим подходом может быть получение экземпляра EntityManager программным способом:

Persistence.getEntityManagerFactory().getEntityManager(persistenceUnitName);

Вы можете реализовать логику, необходимую для присвоения имени единицы сохраняемости в зависимости от ваших собственных критериев. Очевидно, что это имеет все недостатки, связанные с тем, что контейнер больше не управляет постоянством.

1 голос
/ 27 ноября 2011

Как говорится в сообщении об ошибке, атрибуты аннотации Java должны быть постоянными значениями, а не ссылками на переменные. Это ограничение в языках Java, а не JPA. Вам нужно будет найти другой способ сделать то, что вы пытаетесь сделать.

0 голосов
/ 05 декабря 2011

Мое решение не было решением:)

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 в процессе. Попытка замедлить проект.

Я ищу эффективное решение весной.

Спасибо.

0 голосов
/ 01 декабря 2011

Я достиг решения.Я учусь весной.Определенно есть лучшие решения, но я все же хотел поделиться этим решением.

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(); 
   } 
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...