简体   繁体   中英

JPA @ElementCollection @Enumerated not inserting

I am trying to implement basic user/roles

A user can have zero to many roles.

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

}

My Unit Test

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

the problem is, that jpa (backed by hibernate), is not doing the insert on the USER_ROLES table (it is creating it correctly, with the correct composite PK (ROLE, USER_ID), and FK to user.

I can see in the console, that only a single insert is being done, on the user

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

I assume I am just missing something simple.

Elements of collection are inserted into database during flush of persistence context. By default SpringJUnit4ClassRunner triggers a rollback after @Transactional test, therefore automatic flush upon transaction commit doesn't happen.

You need to override this behaviour with @Rollback(false) or @TransactionConfiguraton(defaultRollback = false) , or just trigger an explicit flush using flush() method.

Also if you need to override default properties of collection table you should use @CollectionTable , not @JoinTable .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM