Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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多对多如何仅将数据插入2个表_Java_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

Java Jpa多对多如何仅将数据插入2个表

Java Jpa多对多如何仅将数据插入2个表,java,hibernate,jpa,spring-data-jpa,Java,Hibernate,Jpa,Spring Data Jpa,我有个问题 我有三张桌子: users (id, name, ..) roles (id, name) user-role (user_id, role_id) 当我执行多对多关系和save()时,我有3个插入 用户: 我得到一个错误: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist:... 如果我这样做: @Service("userService"

我有个问题

我有三张桌子:

users (id, name, ..)
roles (id, name)
user-role (user_id, role_id)
当我执行多对多关系和save()时,我有3个插入

用户:

我得到一个错误:

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to  persist:...
如果我这样做:

@Service("userService")
@Transactional
public class UserServiceImpl implements UserDetailsService, ResourceService<User> {
private final static Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

@Autowired
private UserDAO userRepository;
@Autowired
private SystemRoleDAO systemRoleRepository;

@Override
@Transactional(rollbackFor = ResourceException.class)
public User create(User user) throws ResourceException {
    try {
        SystemRole role1 = systemRoleRepository.findOne(6l);
        user.setUserRole(Lists.newArrayList(role1));

        user.setId(62l); // !!! if set user ID - it works CORRECT

        final User saved = userRepository.save(user);
        return saved;
    } catch (DataIntegrityViolationException ex) {
...
@Service(“用户服务”)
@交易的
公共类UserServiceImpl实现UserDetailsService、ResourceService{
私有最终静态记录器Logger=LoggerFactory.getLogger(userserviceinpl.class);
@自动连线
私有用户存储库;
@自动连线
私有系统RoleDao系统RoleRepository;
@凌驾
@事务性(rollbackFor=ResourceException.class)
公共用户创建(用户用户)引发ResourceException{
试一试{
SystemRole角色1=systemRoleRepository.findOne(6l);
user.setUserRole(list.newArrayList(role1));
user.setId(62l);/!!!如果设置了用户ID-它工作正常
保存的最终用户=userRepository.save(用户);
保存的返回;
}捕获(DataIntegrityViolationException ex){
...
用户道:

@Repository
public interface UserDAO extends JpaRepository<User, Long> {
...
@存储库
公共接口UserDAO扩展了JpaRepository{
...
SystemRoleDAO:

@Repository
public interface SystemRoleDAO extends JpaRepository<SystemRole, Long> {
@存储库
公共接口系统RoleDao扩展了JpaRepository{
它工作,但我有3个插入

当我创建一个新用户时,我需要从列表中选择一个角色,将其添加到用户并保存新用户


非常感谢。

我猜userRepository.save()方法中的代码正在调用

entityManager.persist(user);
相反,你应该打电话

entityManager.merge(user);
通过这样做,Hibernate将检查是否已经存在具有相同ID的角色,而不是插入新角色,如果是这种情况,则该角色将附加到用户实体(前提是级联类型包括合并操作)

您需要调用merge的原因是,您使用的角色实体已加载(通过systemRoleService.findOne(“角色\管理员”))并从持久性上下文中分离,因此在您尝试保存用户时会分离此实体。如果角色未分离,则可以调用persist()而不是merge()在用户实体上。

@entity @表(name=“user”)

公共类用户实现可序列化{

public static final String UK_EMAIL = "uk_email";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})  //Make CascadeType.Detached this should solver your problem
@JoinTable(
    name = "system_user_role",
    joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
    inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = id")}
)
private List<SystemRole> userRole;

public List<SystemRole> getUserRole() {
    return userRole;
}
public静态最终字符串UK\u EMAIL=“UK\u EMAIL”;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”)
私人长id;
@ManyToMany(fetch=FetchType.LAZY,cascade={CascadeType.PERSIST,CascadeType.MERGE})//Make CascadeType.Detached这应该可以解决您的问题
@可接合(
name=“系统\用户\角色”,
joinColumns={@JoinColumn(name=“user\u id”,referencedColumnName=“id”)},
inverseJoinColumns={@JoinColumn(name=“role\u id”,referencedColumnName=id”)}
)
私有列表用户角色;
公共列表getUserRole(){
返回用户角色;
}

您如何分配角色?看起来您正在创建新角色,而不是使用现有角色。请避免使用
List
之类的rawtype。请使用
List
代替。我猜会有一个insert,因为您创建了一个新角色,而不是分配了一个现有角色,但您需要发布创建和保存的代码。@user1647166我编辑了您的问题,代码格式有问题。您能检查一下这个问题吗:?看起来相关。@Tom,谢谢,但我以前看过这篇文章,我有一个不同的情况。我需要使用exists角色(我将从列表中选择它们),而不是每次创建新用户时都创建一个新角色。它看起来像是
systemRoleService.findOne
正在调用
role
对象上的
detach
。如果是这样,不要这样做。
detach
用于高级跨会话操作,而不是常规对象操作。您好,谢谢,但我使用
org.springframework.data.jpa.repository.JpaRepository
接口和调用方法
save()
。看看这个我已经更改了代码,但是…:(请查看更改。谢谢。如果我调用
user.setId())
-它工作正常,但我只是在测试时这样做的。保存之前我不知道用户ID…是的,因为在这种情况下,存储库将调用merge()而不是persist()。您必须了解事务中发生了什么。试着在跟踪级别记录org.springframework.transaction
entityManager.persist(user);
entityManager.merge(user);
public static final String UK_EMAIL = "uk_email";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})  //Make CascadeType.Detached this should solver your problem
@JoinTable(
    name = "system_user_role",
    joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
    inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = id")}
)
private List<SystemRole> userRole;

public List<SystemRole> getUserRole() {
    return userRole;
}