首页 > 解决方案 > Hibernate set null 没有保存,则数据已被删除

问题描述

实体:(省略部分属性)

贮存:

@Entity
@Table(name = "t_storage")
public class Storage implements Serializable {

    private static final long serialVersionUID = -8067092629525887737L;

    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String name;

    @ManyToMany(fetch = FetchType.LAZY,cascade= CascadeType.REFRESH)
    @JoinTable(name = "t_purchase_storage", joinColumns = {@JoinColumn(name = "storage_id") },inverseJoinColumns = { @JoinColumn(name = "purchase_id") })
    private List<Purchase> purchases = Lists.newArrayList();

    @ManyToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
    @JoinTable(name = "auth_user_storage", joinColumns = {@JoinColumn(name = "storage_id")}, inverseJoinColumns =
            {@JoinColumn(name = "user_id")})
    private List<User> users = new ArrayList<>();
}

用户:


@Entity
@Table(name = "auth_user")
public class User implements Serializable {

    private static final long serialVersionUID = 2577286098148701829L;

    @Id
    @GeneratedValue
    private Long id;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "auth_user_storage", joinColumns = {@JoinColumn(name = "user_id")}, inverseJoinColumns =
            {@JoinColumn(name = "storage_id")})
    private Set<Storage> storages = Sets.newHashSet();

    @Column(name = "username")
    private String username;
}

步骤:1.想要选择一些存储

        List<Storage> storageList = storageService.findAllStorage(null);
        storageList.forEach(store -> {
            store.setPurchases(null);
            store.setCheckUsers(null);
            store.setUsers(null);
            store.setStorageBins(null);
        });
        return ResponseEntity.ok(JsonResult.success(storageList));

2.AopLog调用UserServiceImpl一个方法

 controllerLog.setOperatorName(userService.findUserNameById(id));

这个 serviceImpl 有 @Transaction


@Service
@Transactional
@Slf4j
public class UserServiceImpl implements UserService {

    @Override
    public String findUserNameById(Long userId) {
        return userRepository.findUsernameById(userId);
    }

}

执行userRepository.findUsernameById时,则删除了setnull之前的属性

日志:

2021-03-29 17:04:06.991 [http-nio-7779-exec-1] INFO  com.~~.api.web.log.AopLog - 【返回值】:<200 OK,class   JsonResult {
    code: 001
    msg: ok
    data: [com.~~.entity.Storage@21]
},{}>

Hibernate: delete from t_checkuser_storage where storage_id=?  
Hibernate: delete from t_purchase_storage where storage_id=?  
Hibernate: delete from auth_user_storage where storage_id=?  
Hibernate: select username from auth_user where id=?  

解决
serviceImpl上的Remove transaction annotation,则没有问题。

或者不设置null,返回VO。

问题
我没有做任何保存或删除操作。为什么保留空白的属性会被删除?

标签: javaspringhibernatetransactions

解决方案


使用 时@Transactional,查询返回的实体在事务期间进行管理。这意味着在提交时,应用于实体的任何更改都将传播到数据库。因此,将这些值设置为 null 等效于数据库上的更新查询。

当您删除@Transactional时,实体在查询返回后立即停止管理。因此,更改不会传播到数据库。


推荐阅读