La colección perezosa se inicializó con entusiasmo (transaccional + carga diferida)
Frecuentes
Visto 837 equipos
2
La clase de ciudad se asigna a la base de datos.
@Entity
@Table(name = "City")
public class City implements Serializable, IRelationsQualifier
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
//-------------------------------------------------------
@JsonIgnore
@NotFound(action = NotFoundAction.IGNORE)
@ManyToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},
targetEntity = Event.class
)
@JoinTable(
name="CityEvent",
joinColumns = @JoinColumn( name="city_id"),
inverseJoinColumns = @JoinColumn( name="event_id")
)
private Set<Event> eventList = new HashSet<Event>();
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
@JsonIgnore
public Set<Event> getEvents()
{
return eventList;
}
@JsonIgnore
public void setEvents(Set<Event> events)
{
this.eventList = events;
}
}
Capa Dao para City.
package com.globerry.project.dao;
// removing imports to make it easier to read
@Repository
public class CityDao implements ICityDao
{
@Autowired
SessionFactory sessionFactory;
@Autowired
@Override
public City getCityById(int id)
{
City city = (City) sessionFactory.getCurrentSession().load(City.class, id);
return city;
}
}
Prueba:
package com.globerry.project.dao;
// removing time imports to make it easier to read.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/META-INF/spring/daoTestContext.xml")
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class, ContextLoaderListener.class
})
public class CityDaoTest {
@Test
@Transactional(readOnly=false)
public void LazyTest()
{
City city1 = new City();
city1.setName("Bobryjsk1");
try
{
cityDao.addCity(city1);
}
catch (MySqlException e)
{
e.printStackTrace(System.err);
}
Event ev = new Event();
ev.setName("Disnayland");
eventDao.addEvent(ev, city1);
ev = new Event();
ev.setName("Disnayland5");
eventDao.addEvent(ev, city1);
System.err.println("1");
city1 = cityDao.getCityById(city1.getId());//there i saw in debug that events have been already inizialized
System.err.println("2");
System.err.println(Hibernate.isInitialized(city1.getEvents()));//returns true
Iterator<Event> it = city1.getEvents().iterator();
System.err.println("3");
ev = it.next();
System.err.println(ev.getName());
ev = new Event();
ev.setName("Disnayland55");
eventDao.addEvent(ev, city1);
}
}
contexto raíz:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- <jdbc:embedded-database id="dataSource" type="H2"/> -->
<context:annotation-config />
<context:component-scan base-package="com.globerry.project.domain" />
<context:component-scan base-package="com.globerry.project.dao" />
<context:component-scan base-package="com.globerry.project.service" />
<!-- Файл с настройками ресурсов для работы с данными (Data Access Resources) -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Менеджер транзакций -->
<!-- Настройки бина dataSource будем хранить в отдельном файле -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:/META-INF/jdbc.properties" />
<!-- Непосредственно бин dataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="${jdbc.databaseurl}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<!-- Настройки фабрики сессий Хибернейта -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:packagesToScan="com.globerry.project.Dao">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory">
<qualifier value="transactionManager"/>
</bean>
</beans>
Cuando estoy usando el método 'getCityById()' en mi 'LazyTest()' en el modo de depuración, obtengo un resultado extraño. En la depuración, veo que mi colección de eventos se inicializó antes de usarla por primera vez. Pero estoy usando Lazy Fetch Strategy. ¿Lo que está mal?
1 Respuestas
1
Eso es porque ya está en la sesión. Load devuelve el objeto City que acaba de crear, sin obtenerlo de la base de datos.
Agregue el siguiente código antes de la llamada getCityById: obtendrá el resultado que espera.
sessionFactory.getCurrentSession().flush()
sessionFactory.getCurrentSession().clear()
Respondido 04 Jul 12, 11:07
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas spring hibernate lazy-loading transactional or haz tu propia pregunta.
¿Puedes aceptar la respuesta? meta.stackexchange.com/questions/5234/… - gkamal