У меня есть некоторые проблемы с пониманием того, как пружина управляет спящими сущностями и выполняет ленивый процесс загрузки.Жизненный цикл объекта спящего режима и период цикла сеанса внутри весенней транзакции
Так для этого случая мы должны субъектам
@Entity
public class EntityA{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.REFRESH})
private Collection<EntityB> bss= new ArrayList<EntityB>();
и agregated сущностей
@Entity
public class EntityB{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToMany(mappedBy="bss")
private Collection<EntityA> ass= new ArrayList<EntityA>();
тогда у меня есть простой бизнес-класс отмечен как транзакционные:
@Component
@Scope("session")
@Transactional(propagation=Propagation.TRIED_EVERY_SINGLE_ONE)
public class GenericTestBean {
private EntityA entityA;
@Autowired
private IGenericDAO genericDAO;
public GenericTestBean() {
System.out.println("bean creado!");
}
public void testQuery() {
entityA= genericDAO.get(EntityA.class, 1l);
System.out.println(TransactionIndicatingUtil.getTransactionStatus(true));
System.out.println("is element atached? :" + genericDAO.isAtached(entityA));
//this.loadData();
}
public void loadData(){
System.out.println(TransactionIndicatingUtil.getTransactionStatus(true));
System.out.println("is element atached? :" + genericDAO.isAtached(currentCompany));
System.out.println(entityA.getBss.size());
}
}
и а Простой класс испытаний
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "applicationContext.xml" })
@WebAppConfiguration
public class EntityQueryTest {
// @Autowired
// private SessionFactory sessionFactory;
@Autowired
GenericTestBean genericTestBean;
@Test
public void consultarCompania(){
genericTestBean.testQuery();
genericTestBean.loadData();
}
, что Im guessin что должно случиться: 1. GenericTestBean получает экземпляр 2. testQuery вызывается из-за пределов прокси запуска транзакции 2. LoadData называется, прокси-сервер видит активную транзакцию, и принимает сущее ресурсы 3. данные retrieived 4. transacion закрыт ...
Но это не происходит, кажется, есть две разные транзакции в каждом вызове метода, и объект получает отдельностоящий между вызовами, выдав ленивое исключение инициализации.
фактический журнал вывод заключается в следующем:
bean creado! --here the object get created
Hibernate: select company0_.companyId as ..... --here the first query get executed
[com.pe.controlLines.data.dao.GenericTestBean.testQuery] --here we check the name for the transaction
is element atached? :true --and see if the element is attached to the session
[com.pe.controlLines.data.dao.GenericTestBean.loadData] --this is in the second method call (with a different transaction name :O)
is element atached? :false --both now, the same element get detached
Я попытался повторно прикрепление сущности, но это дает мне новый запрос к базе данных (новый запрос к таблице EntityA посылаются плюс запрос, чтобы получить объекты, которые мне действительно не нравятся).
Im надеясь сохранить один дополнительный запрос только для того, чтобы иметь ленивую загрузку, или это должно быть так ?, или, может быть, у меня некорректная конфигурация?
Pdta: Я думаю, что опция фильтра просмотра даже хуже, чем опция повторного присоединения, это может привести к серьезным проблемам с производительностью при высоком уровне параллелизма.
Можно ли прояснить поведение контекстов транзакций между вызовами методов и как это связано с сеансом и состоянием сущностей?
реализация TransactionIndicatingUtil взята отсюда http://java.dzone.com/articles/monitoring-declarative-transac?page=0,1
и общий дао построен после того, как эта идея General or specific DAO to record delivery with information from multiple tables?
Update
в случае какого-либо использования, здесь весной конфигурации файл
<context:component-scan base-package="xxxxxx" />
<context:annotation-config />
<context:spring-configured />
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- Data Source Declaration -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/xxxx" />
<property name="username" value="xxxxx" />
<property name="password" value="xxxxx" />
<property name="initialSize" value="2" />
<property name="minIdle" value="0" />
<property name="minEvictableIdleTimeMillis" value="120000" />
<property name="maxActive" value="20" />
<property name="maxWait" value="5000" />
</bean>
<!-- Session Factory Declaration <bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> -->
<!-- Session Factory Declaration -->
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan">
<list>
<value>com.xx.xx.xx.xx</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.search.default.directory_provider">filesystem</prop>
<prop key="hibernate.search.default.indexBase">C:/DEVELOPMENT/lucene/indexes</prop>
</props>
</property>
</bean>
<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
<!-- Transaction Manager is defined -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory"/>
</bean>
Я не совсем уверен, что если вы говорите о (закомментирован) внутренний вызов из testQuery() в loadData(), но если вы тогда: http://stackoverflow.com/a/8233459/1356423 –
Nop, на самом деле, когда я раскомментирую его, он работает так, как я ожидаю: s это может быть проблема с конфигурацией Spring Spring? –