我有一个名为SecurityUser的实体,它通过名为SECURITY_USER_ROLE的多对多映射表映射到另一个实体SecurityRole。
SecurityUser实体:
@Entity
@Named("securityUser")
@Table(name = "SECURITY_USER")
@NamedQueries({
@NamedQuery(
name = SecurityUser.GET_ALL_USERS_WITH_ROLES,
query = "select u from SecurityUser u join fetch u.securityRoles join fetch u.userLanguage")})
public class SecurityUser extends AuditEntity implements Serializable {
public static final String GET_ALL_USERS_WITH_ROLES = "getAllUsersWithRoles";
@Id
@Column(name = "USER_LOGIN")
private String userLogin;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userLogin")
private Set<UserLastSelection> userLastSelections = new HashSet<UserLastSelection>(0);
@ManyToMany(targetEntity = SecurityRole.class, fetch = FetchType.LAZY)
@JoinTable(name = "SECURITY_USER_ROLE", joinColumns = @JoinColumn(name = "USER_LOGIN"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
private List<SecurityRole> securityRoles;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "USER_LOGIN")
private UserLanguage userLanguage;
SecurityRole实体:
@Entity
@Named("securityRole")
@Table(name = "SECURITY_ROLE")
@Id
@SequenceGenerator(name = "ROLE_ID_GENERATOR", sequenceName = "SECURITY_ROLE_ID_SEQ")
@GeneratedValue(generator = "ROLE_ID_GENERATOR")
@Column(unique = true, nullable = false, precision = 12)
private Long id;
@Length(max = 50)
@Column(name = "ROLE_NAME")
private String roleName;
@OneToMany(mappedBy = "securityRole", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@LazyCollection(LazyCollectionOption.TRUE)
private List<SecurityRolePermission> securityRolePermission;
@OneToMany(mappedBy = "securityRole", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@LazyCollection(LazyCollectionOption.TRUE)
private List<SecurityRoleLookup> securityRoleLookups;
SecurityUserRole实体:
@Entity
@Named("securityUserRole")
@Table(name = "SECURITY_USER_ROLE")
public class SecurityUserRole extends AuditEntity implements Serializable {
@Id
@Column(name = "ID")
@GeneratedValue(generator = "UserRoleIdSeq")
@SequenceGenerator(name = "UserRoleIdSeq", sequenceName = "SECURITY_USER_ROLE_ID_SEQ")
private Long id;
@ManyToOne
@JoinColumn(name = "USER_LOGIN")
@Fetch(FetchMode.SELECT)
@LazyToOne(LazyToOneOption.NO_PROXY)
private SecurityUser user;
@OneToOne
@JoinColumn(name = "ROLE_ID")
@Fetch(FetchMode.SELECT)
@LazyToOne(LazyToOneOption.NO_PROXY)
private SecurityRole securityRole;
@Column(name = "ROLE_STATUS")
private String roleStatus;
我想使用命名查询GET_ALL_USERS_WITH_ROLES
获取securityUsers。但是,当我使用我的命名查询来获取SecurityUsers列表时,在事务结束时,Hibernate会在特定用户的映射表上运行delete语句,然后在最初删除的行中添加回来。
使用命名查询的方法:
public List<Object[]> fetchUsers() {
List<SecurityUser> securityUsers = securityUserDAO.fetchAllSecurityUsersWithRoles();
List<Object[]> userArrayList = new ArrayList<>();
return userArrayList;
}
SecurityUserDAO:
public class SecurityUserDAO extends BaseDAO {
@SuppressWarnings("unchecked")
public List<SecurityUser> fetchAllSecurityUsersWithRoles() {
List<SecurityUser> securityUsers = entityManager.createNamedQuery(SecurityUser.GET_ALL_USERS_WITH_ROLES)
.getResultList();
return securityUsers;
}
}
控制台输出:
Hibernate:
delete
from
SECURITY_USER_ROLE
where
USER_LOGIN=?
MSG=binding parameter [1] as [VARCHAR] - user_A
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 4
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 1570
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 15
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 26
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 9
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 1546
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 1387
Hibernate:
insert
into
SECURITY_USER_ROLE
(USER_LOGIN, ROLE_ID)
values
(?, ?)
MSG=binding parameter [1] as [VARCHAR] - user_A
MSG=binding parameter [2] as [BIGINT] - 1280
11:56:48,783 INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (http-localhost/127.0.0.1:8080-1) HHH000010: On release of batch it still contained JDBC statements
11:56:48,784 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-1) SQL Error: 1400, SQLState: 23000
11:56:48,786 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-1) ORA-01400: cannot insert NULL into ("SCHEMA_NAME"."SECURITY_USER_ROLE"."ROLE_STATUS")
正在插入的每个用户登录/角色ID组合都存在于删除之前的映射表SECURITY_USER_ROLE
中。 user_A存在于SECURITY_USER
表中,role_ids存在于SECURITY_ROLE
表中。插入失败,因为ROLE_STATUS是SECURITY_USER_ROLE
上的不可为空的列。即使我没有触及我提取的列表,我仍然会获得这些删除和插入语句。 为什么Hibernate会从我的映射表中删除行,然后在运行select语句的命名查询时尝试重新添加它们?
我正在使用JBoss EAP 6.1和hibernate版本4.2.14.Final