2012-04-19 59 views
1

我想實現基本的用戶/角色JPA @ElementCollection @Enumerated不插入

用戶可以有0到多個角色。

public enum Role { 
    ROLE_USER, 
    ROLE_ADMIN; 
} 

@Entity 
@Table(name = "USERS") 
public class User implements Serializable { 

    private static final long serialVersionUID = 2936736450886451500L; 
    private Long id; 
    private Individual individual; 
    private Set<Role> roles = new HashSet<Role>(); 

    @Id 
    @Column(name = "ID") 
    @GeneratedValue 
    public Long getId() { 
    return id; 
    } 

    @SuppressWarnings("unused") 
    private void setId(Long id) { 
    this.id = id; 
    } 

    @ElementCollection(targetClass=Role.class) 
    @JoinTable(name = "USER_ROLES", joinColumns = @JoinColumn(name = "USER_ID")) 
    @Enumerated(EnumType.STRING) 
    @Column(name = "role", nullable = false) 
    public Set<Role> getRoles() { 
    return roles; 
    } 

    public void setRoles(Set<Role> roles) { 
    this.roles = roles; 
    } 

    public void addRole(Role role) { 
    roles.add(role); 
    } 

} 

我的單元測試

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"classpath:/META-INF/spring/resources/resource-context.xml", "classpath:/META-INF/spring/services/persistence-context.xml"}) 
public class UserDaoJpaImplTest { 

@Autowired 
UserDao userDao; 

@Transactional 
@Test 
public void testCreate() { 
    User user = new User(); 
    user.setIndividual(new Individual()); 
    user.addRole(Role.ROLE_USER); 
    user.addRole(Role.ROLE_ADMIN); 
    userDao.create(user); 

    Assert.assertNotSame(user.getId(), 0); 
} 

的問題是,JPA(由Hibernate支持),是不是做對USER_ROLES表插入(它是正確創建它,用正確的複合PK (角色,USER_ID)和FK用戶。

我可以在控制檯中看到,只有單個插入正在做,用戶

Hibernate: insert into USERS (INDIVIDUAL_ID) values (?) 
Hibernate: insert into INDIVIDUALS values () 

我假設我只是缺少一些簡單的東西。

+0

你用'@RunWith(SpringJUnit4ClassRunner.class)'運行測試嗎? – axtavt 2012-04-19 12:33:14

+0

@axtavt是的,我喜歡。更新超過 – kabal 2012-04-19 12:42:35

回答

3

集合的元素在持久化上下文刷新期間插入到數據庫中。默認SpringJUnit4ClassRunner@Transactional測試後觸發回滾,因此事務提交時自動刷新不會發生。

您需要用@Rollback(false)@TransactionConfiguraton(defaultRollback = false)覆蓋此行爲,或者僅使用flush()方法觸發顯式刷新。

此外,如果您需要覆蓋收集表的默認屬性,則應使用@CollectionTable而不是@JoinTable

+0

非常感謝,我以爲我瘋了。我認爲這在做這種TDD(我使用這個術語鬆散地)方面略有缺點,因爲測試不是「準確的」,也就是說,我不想在事後繼續測試。至少我知道發生了什麼/爲什麼發生 – kabal 2012-04-19 12:58:01

+1

明確調用flush是不夠的,你必須設置事務配置來實際提交數據。否則,事務將回滾並且flush不會持久化任何事情。 – Leonel 2012-06-14 19:45:19