2012-07-04 78 views
2

城市類被映射到數據庫。懶惰集合熱切初始化(事務+延遲加載)

@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; 
    } 


} 

Dao layer for 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; 
    } 
} 

測試:

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); 
    } 

} 

根上下文:

<?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> 

當我使用的方法 'getCityById()' 在我的 'LazyTest()' 在調試模式下,我得到奇怪的結果。在調試中,我看到我的事件集合已初始化,在我第一次使用它之前。但我正在使用懶惰取指策略。哪裏不對?

回答

1

這是因爲它已經在會話中。加載返回剛剛創建的City對象 - 不從數據庫中獲取它。

在getCityById調用之前添加以下代碼 - 您將獲得您期待的結果。

sessionFactory.getCurrentSession().flush() 
sessionFactory.getCurrentSession().clear() 
+0

謝謝!現在它工作了! – user1497908

+0

你能接受答案 - http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – gkamal

+0

當然。謝謝 – user1497908