Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA/Hibernate“;简单的;OneToMany单向/清除设置不起作用_Java_Hibernate_Jpa_One To Many - Fatal编程技术网

Java JPA/Hibernate“;简单的;OneToMany单向/清除设置不起作用

Java JPA/Hibernate“;简单的;OneToMany单向/清除设置不起作用,java,hibernate,jpa,one-to-many,Java,Hibernate,Jpa,One To Many,我不知道我做错了什么,但显然我无法与hibernate建立简单的一对一关系 以下是我的表格,它们在DB中的外观: 我将只展示相关的部分,这样问题就不会变得臃肿。 我的用户看起来像 @Entity(name = "CORE_USER") public class User extends AbstractPersistentObject { ... @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY) @Jo

我不知道我做错了什么,但显然我无法与hibernate建立简单的一对一关系

以下是我的表格,它们在DB中的外观: 我将只展示相关的部分,这样问题就不会变得臃肿。 我的用户看起来像

@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")
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());
}
jpa不应该把用户ID放在它所属的地方吗?我想要的是一种单向关系,用户知道UserRoleParams,而不是相反。就像这里的例子一样

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

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

现在我有一个问题,清除集合将不会持续。我的测试失败,因为如果
集合
为空,则第二次检查失败。它显示参数仍然设置。

字段
User.userRoleParams
UserRoleParam.User
是双向关系的一部分。要做到这一点,您必须添加
mappedBy=“user”
@OneToMany

不能将这两部分作为独立关系(即单向1-N和单向N-1)重用同一FK列(“用户ID”)

至于,单向1-N的唯一用法在另一边没有字段(而你在关系的另一边有字段)


用户在回答此问题后已更改其问题我为什么要麻烦?

字段
User.UserRoleParam
UserRoleParam.User
是双向关系的一部分。要做到这一点,您必须添加
mappedBy=“user”
@OneToMany

不能将这两部分作为独立关系(即单向1-N和单向N-1)重用同一FK列(“用户ID”)

至于,单向1-N的唯一用法在另一边没有字段(而你在关系的另一边有字段)



用户在回答此问题后已更改其问题我为什么要麻烦?

在保存核心用户角色参数之前先保存用户您没有将
mappedBy=“user”
放在
user.userRoleParams
字段上,因为这是双向的relation@Stimpson:我加载的用户已经存在,正如您在测试开始时看到的,我加载用户以检查参数是否为空。然后您保存id=null的用户。您是否启用了autoincrement或正在使用id序列?请启用调试并显示一些sql语句保存用户,然后再保存核心用户角色参数您尚未将
mappedBy=“user”
放在
user.userRoleParams
字段中,因为这是双向的relation@Stimpson:我加载的用户已经存在,正如您在测试开始时看到的,我加载用户以检查参数是否为空。然后您保存id=null的用户。您是否已启用自动增量,或者正在对id使用序列?请启用调试并显示一些sql语句您是对的。。。那样的话。。。那是当我在玩的时候,我不小心发布了错误的代码。我想要的是JPA映射侧的单向关系。它在表CORE_USER_ROLE_PARAM中有自己的列,即USER_ID。如果您有更多耐心,或者停止大喊大叫(用大写字母书写),我将不胜感激。如果问题发生变化,您将无能为力;)你是对的。。。我犯了一个错误,在问题中复制了一个错误的代码。如果我解决了老问题,我不想提出新问题你是对的。。。那样的话。。。那是当我在玩的时候,我不小心发布了错误的代码。我想要的是JPA映射侧的单向关系。它在表CORE_USER_ROLE_PARAM中有自己的列,即USER_ID。如果您有更多耐心,或者停止大喊大叫(用大写字母书写),我将不胜感激。如果问题发生变化,您将无能为力;)你是对的。。。我犯了一个错误,在问题中复制了一个错误的代码。如果我解决了旧问题,我不想提出新问题
@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);
}
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:
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID", nullable = false)
private Set<UserRoleParam> userRoleParams = new HashSet<UserRoleParam>();