2013-03-05 44 views
6

我似乎有一個相當奇怪的問題。我在JSP中顯示用戶和他們的角色。出於某種原因,角色僅在首次加載頁面時顯示。我刷新頁面,角色都從數據庫中刪除!爲什麼Hibernate刪除我的收藏條目時,我所做的只是一個列表?

我的設置是標準的Spring MVC,JPA + Hibernate(通過Spring數據)應用程序。 (彈簧3.2.x中,休眠4.1.8)

我有兩個實體 - UserRole,如下所示(假設setter和getter)

@Entity 
public class User { 
    @Id 
    @GeneratedValue 
    private int id; 

    private String name; 

    @ManyToMany 
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) 
    private Set<Role> roles = new HashSet<>(); 
} 

@Entity 
public class Role { 
    @Id 
    private String id; 

    private String name; 
} 

我有一個Spring數據存儲庫,其不定義任何額外的方法。

public interface UserRepository extends CrudRepository<User, Integer> { 
} 

我有一個服務和一個控制器,其相關方法如下。

// service 
@Transactional(readOnly = true) 
public Iterable<User> findAll() { 
    return userRepository.findAll(); 
} 

// controller 
@RequestMapping 
public String showUsers(ModelMap model) { 
    model.put("users", userService.findAll()); 

    return "admin/users"; 
} 

在我的JSP中,我試圖顯示所有的用戶和任何關聯的角色。

<c:forEach var="user" items="${users}"> 
    <tr> 
     <td>${user.name}</td> 
     <td> 
      <c:forEach var="role" items="${user.roles}"> 
       ${role.name} 
      </c:forEach> 
     </td> 
    </tr> 
</c:forEach> 

就像我剛纔所說,在我user_role表中的記錄本頁面已經被渲染之後被刪除。

啓用後DEBUGorg.hibernate和啓用查詢日誌記錄,這裏是我在日誌中發現:

22:36:25 DEBUG Collection dereferenced: [com.adarshr.domain.User.roles#1] [Collections.java:76] 
22:36:25 DEBUG Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects [AbstractFlushingEventListener.java:117] 
22:36:25 DEBUG Flushed: 0 (re)creations, 0 updates, 1 removals to 1 collections [AbstractFlushingEventListener.java:124] 
22:36:25 DEBUG Deleting collection: [com.adarshr.domain.User.roles#1] [AbstractCollectionPersister.java:1124] 
22:36:25 DEBUG 
    delete 
    from 
     user_role 
    where 
     user_id=? [SqlStatementLogger.java:104] 
22:36:25 DEBUG Done deleting collection [AbstractCollectionPersister.java:1182] 

很顯然有鬼是怎麼回事。爲什麼我的收藏首先被取消了?

這是我的JPA實體管理器工廠定義。

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="mainDataSource" /> 
    <property name="packagesToScan" value="com.adarshr.domain" /> 
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
    </property> 
    <property name="jpaProperties"> 
     <value> 
      hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 
      hibernate.format_sql=${hibernate.format.sql} 
      hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy 
      hibernate.show_sql=${hibernate.show.sql} 
      hibernate.enable_lazy_load_no_trans=true 
     </value> 
    </property> 
</bean> 

這裏我錯過了一些東西明顯?

+0

你從哪裏得到「enable_lazy_load_no_trans」?我能找到的關於它的是人們說這是很有問題的,不推薦使用。 – 2013-03-06 05:15:46

+0

從http://stackoverflow.com/questions/578433/how-to-solve-lazy-initialization-exception-using-jpa-and-hibernate-as-provider – adarshr 2013-03-06 07:22:29

+0

「謹慎使用是一種輕描淡寫!」 「這實際上只是一個以基準爲目標的功能......」「......在一般用途中這是一個非常糟糕的主意。」 「冒自己的風險。」 「......它不是我們真正認爲人們應該使用而不知道可能的後果的功能。」 https://hibernate.onjira.com/browse/HHH-7457嗯,你感覺到那裏的主題嗎?不要使用它。 – 2013-03-06 13:33:37

回答

5

由於您發佈的代碼似乎正確,我在這裏猜測。

我建議的第一件事就是刪除這個初始化(它似乎是刪除角色的唯一地方),雖然這是一個好主意,但一般來說(見下面的評論)我認爲可能會干擾hibernate.enable_lazy_load_no_trans=true已經已知leak connections過去:

private Set<Role> roles = new HashSet<>(); 

第二次嘗試將檢查什麼變化,如果你也有註釋你的mappedBy關係多對多的反側。

第三次嘗試是,如果急於加載集合,則可以使用任何所需的FetchType,Hibernate.initialize()修復問題(加重enable_lazy_load_no_trans位置甚至更多)。

最後一個是擺脫enable_lazy_load_no_trans和使用OpenSessionInView

編輯:啊,最後一個,你可能*有它這個bug(休眠4.1.8和4.1.9的影響): https://hibernate.onjira.com/browse/HHH-7971

所以用4.1來拍攝。7可以給出更好的結果(或者更糟)。

*其中可能的目的是:「您的案例非常相似,您被邀請將您的代碼作爲錯誤報告中的測試用例發送」。

+0

壞主意。 *始終*將集合類型初始化爲空集合。我保證這不是根本原因。 – 2013-03-06 03:08:58

+0

@Ryan Stewart我同意,我的想法可能是hibernate.enable_lazy_load_no_trans = true的問題,我正在爲此做點努力。 – 2013-03-06 03:10:17

+0

剛剛看到了錯誤報告。我有完全相同的問題。我會嘗試發送一個測試用例。降級到4.1.7似乎解決了這個問題。但是,沒有初始化集合並沒有什麼區別。即使有OEMIVFilter工作。 – adarshr 2013-03-06 22:38:16

相關問題