gpt4 book ai didi

java - JPA/Hibernate "simple"OneToMany 单向/清除集不起作用

转载 作者:行者123 更新时间:2023-12-02 02:50:26 25 4
gpt4 key购买 nike

我不知道我做错了什么,但显然我无法与 hibernate 创建简单的 OneToMany 关系。

这是我的表格在数据库中的外观: enter image description here我只会展示相关部分,因此问题不会变得臃肿。我的用户看起来像

@Entity(name = "CORE_USER")
public class User extends AbstractPersistentObject {

...

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name = "CORE_USER_TO_ROLE",
joinColumns = { @JoinColumn(name = "USER_ID") },
inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
private Set<UserRole> roles = new HashSet<UserRole>();

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID")
private Set<UserRoleParam> userRoleParams = new HashSet<UserRoleParam>();

...(getter and setters)

}

此处核心用户角色参数实体

@Entity(name = "CORE_USER_ROLE_PARAM")
public class UserRoleParam extends AbstractPersistentObject {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ROLE_ID")
private UserRole userRole;

@Column(name = "ROLE_PARAMETER")
private String paramter;

...(getter and setter)....
}

UserRole 实体

@Entity(name="CORE_USER_ROLE")
public class UserRole extends AbstractPersistentObject {

@Enumerated(EnumType.STRING)
@Column(name = "ROLE_NAME", length = 30, nullable=false, unique=true)
private UserRoleEnum roleName;

...(getter and setters)
}

当我在测试中这样做时:

@Test
@Transactional(propagation = Propagation.NEVER)
public void saveUserRoleParametersTest() throws Exception {

// load an user which exists and check params is zero
UserDTO userDTO = userService.getUserDTO(Users.DE678_ACTIVE_ALLROLES.getObject().getId());
Assert.assertNotNull(userDTO);
Assert.assertNotNull(userDTO.getUserRoleParams());
Assert.assertEquals(0, userDTO.getUserRoleParams().size());

Map<UserRoleEnum, List<String>> userRoleParams = new HashMap<>();
userRoleParams.put(UserRoleEnum.BASIC, new ArrayList<>());
userRoleParams.get(UserRoleEnum.BASIC).add("BASIC_PARAM");

// save params to user
userService.saveUserRoleParameters(Users.DE678_ACTIVE_ALLROLES.getObject().getId(), userRoleParams);


userDTO = userService.getUserDTO(Users.DE678_ACTIVE_ALLROLES.getObject().getId());
Assert.assertNotNull(userDTO);
Assert.assertNotNull(userDTO.getUserRoleParams());
Assert.assertEquals(1, userDTO.getUserRoleParams().size());
Assert.assertEquals(1, userDTO.getUserRoleParams().get(UserRoleEnum.BASIC).size());
Assert.assertTrue(userDTO.getUserRoleParams().get(UserRoleEnum.BASIC).contains("BASIC_PARAM"));

// delete params of user
userService.saveUserRoleParameters(Users.DE678_ACTIVE_ALLROLES.getObject().getId(), null);

userDTO = userService.getUserDTO(Users.DE678_ACTIVE_ALLROLES.getObject().getId());
Assert.assertNotNull(userDTO);
Assert.assertNotNull(userDTO.getUserRoleParams());
Assert.assertEquals(0, userDTO.getUserRoleParams().size());
}

这也是我调用的用户服务方法:

@Override
public void saveUserRoleParameters(final String userId, final Map<UserRoleEnum, List<String>> userRoleParams) throws UserNotFoundException {
User user = userDAO.get(userId);

if (user == null) {
throw new UserNotFoundException(userId);
}

if (userRoleParams == null || userRoleParams.isEmpty()) {
user.getUserRoleParams().clear();
} else {
List<UserRole> roles = userDAO.getUserRolesByEnums(userRoleParams.keySet());
Map<UserRoleEnum, UserRole> enumToEntity = new HashMap<>();
roles.stream().forEach(r -> enumToEntity.put(r.getRoleName(), r));

for (Entry<UserRoleEnum, List<String>> entry : userRoleParams.entrySet()) {
UserRoleParam urp = new UserRoleParam(enumToEntity.get(entry.getKey()), entry.getValue().stream().collect(Collectors.joining(";")));
user.getUserRoleParams().add(urp);
}
}
userDAO.saveOrUpdate(user);
}

问题是我的测试在第一次调用 saveUserRoleParameters 服务方法时失败,这是(编辑:现在启用了 sql 日志):

DEBUG [main] 12.05.17 08:46:50.264  org.hibernate.engine.jdbc.spi.SqlStatementLogger@logStatement: select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.ACTIVE as ACTIVE1_38_0_, user0_.APP_LANG as APP_LANG2_38_0_, user0_.DEFAULT_MODULE as DEFAULT_3_38_0_, user0_.ORGA_UNIT as ORGA_UNI4_38_0_, user0_.USER_FULL_NAME as USER_FUL5_38_0_, user0_.USER_NAME as USER_NAM6_38_0_ from CORE_USER user0_ where user0_.id=?
DEBUG [main] 12.05.17 08:46:50.270 org.hibernate.engine.jdbc.spi.SqlStatementLogger@logStatement: select userrole0_.id as id1_0_, userrole0_.version as version2_0_, userrole0_.ROLE_NAME as ROLE_NAM1_41_ from CORE_USER_ROLE userrole0_ where userrole0_.ROLE_NAME in (?)
DEBUG [main] 12.05.17 08:46:50.287 org.hibernate.engine.jdbc.spi.SqlStatementLogger@logStatement: select userrolepa0_.USER_ID as USER_ID3_0_0_, userrolepa0_.id as id1_42_0_, userrolepa0_.id as id1_0_1_, userrolepa0_.version as version2_0_1_, userrolepa0_.ROLE_PARAMETER as ROLE_PAR1_42_1_, userrolepa0_.ROLE_ID as ROLE_ID2_42_1_ from CORE_USER_ROLE_ROLE_PARAM userrolepa0_ where userrolepa0_.USER_ID=?
DEBUG [main] 12.05.17 08:46:50.290 org.hibernate.engine.jdbc.spi.SqlStatementLogger@logStatement: insert into CORE_USER_ROLE_PARAM (version, ROLE_PARAMETER, ROLE_ID, id) values (?, ?, ?, ?)
WARN [main] 12.05.17 08:46:50.291 org.hibernate.engine.jdbc.spi.SqlExceptionHelper@logExceptions: SQL Error: 23502, SQLState: 23502
ERROR [main] 12.05.17 08:46:50.291 org.hibernate.engine.jdbc.spi.SqlExceptionHelper@logExceptions: NULL nicht zulässig für Feld "USER_ID"
NULL not allowed for column "USER_ID"; SQL statement:
insert into CORE_USER_ROLE_ROLE_PARAM (version, ROLE_PARAMETER, ROLE_ID, id) values (?, ?, ?, ?) [23502-175]
WARN [main] 12.05.17 08:46:50.291 org.hibernate.engine.jdbc.spi.SqlExceptionHelper@logExceptions: SQL Error: 23502, SQLState: 23502
ERROR [main] 12.05.17 08:46:50.292 org.hibernate.engine.jdbc.spi.SqlExceptionHelper@logExceptions: NULL nicht zulässig für Feld "USER_ID"
NULL not allowed for column "USER_ID"; SQL statement:

jpa 不应该将 UserId 放在它所属的地方吗?我想要的是一种单向关系,其中用户知道 UserRoleParams,但反之则不然。就像这里的例子 http://www.objectdb.com/api/java/jpa/annotations/relationship

编辑#2:我找到了解决方案。我在用户实体上添加了以下内容:

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID", nullable = false)
private Set<UserRoleParam> userRoleParams = new HashSet<UserRoleParam>();

现在我遇到了清除集合不会被持久化的问题。我的测试失败,因为第二次检查 Set 是否为空失败。这表明参数仍然设置。

最佳答案

字段User.userRoleParamsUserRoleParam.user是双向关系的一部分。为此,您必须添加mappedBy="user"@OneToMany 一侧。

您不能将这两个部分作为独立关系(即单向 1-N 和单向 N-1)重复使用相同的 FK 列(“USER_ID”)。

至于your documentation you linked to in the comments ,单向 1-N 的唯一使用在另一侧没有字段(并且您在关系的另一侧确实有一个字段)。

自此回答以来,用户已更改了他们的问题!我为什么要打扰?

关于java - JPA/Hibernate "simple"OneToMany 单向/清除集不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43930693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com