美文网首页
Spring JPA自动更新诡异现象

Spring JPA自动更新诡异现象

作者: 暗夜行者 | 来源:发表于2020-02-17 19:16 被阅读0次

    最近在操作spring data的时候遇到一个奇怪的问题。
    第一,更改了实体entity,数据库会被自动更新
    第二,更改了实体的entity,相关实体解析出问题

    场景如下,有一个user表,这个表中有role 和project .
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Entity
    @Table(name = "User")
    public class User extends BaseEntity{
    @ManyToOne
    private Role role;
    @ManyToOne
    private Project project;
    }

    在数据库中,User表这两个字段分别为role_id 和 project_id
    role和project实体中并未配置onetomany的映射. 下面奇妙的事情发生了,
    第一我更新User实体,仅仅是更新实体,并没有进行save操作,竟然数据库中的内容被自动更新,自动执行了了一遍save的操作,按照Id全员update。
    long roleId = userRoleHandler.checkAndUpdateUserRole();
    if(roleId > 0) {
    Role role = new Role();
    role.setId(roleId);
    user.setRole(role);
    }
    这样的情况,即便我新建了一个user , 全量赋值之后执行,依然会被自动更新掉,而且之后对role的操作也会作用到原来的user。
    解决方法是写了@query
    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update AppUser set first_lgn = ?1,last_lgn =?2 , help_flg = ?3, update_dt = ?4 , project_id = ?5, role_id = ?6 where id = ?7 ", nativeQuery = true)
    void updateUserByQueryMySql(boolean firstLogin, Date lastLgn, boolean showHelp,Date updateDate,Long projectId,Long roleId, Long id);

    这样做之后,不会再影响到原来的user,但实际上是save自动更新还是会被执行,只是被这个query覆盖掉了。

    接下来发生第二个诡异事件:
    project中有client实体
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Entity
    public class Project extends BaseEntity {
    @ManyToOne
    @JoinColumn(nullable = false, name = "client_id")
    protected Client client;
    }
    client中的属性就相对很多:
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Entity
    @Table(name = "Client")
    public class Client extends BaseEntity {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 3182405782441627318L;
    
    /** The name. */
    @ApiObjectField(description = "Name of the Company/Client")
    @Column(nullable = false)
    protected String name;
    
    /** The revenue. */
    @ApiObjectField(description = "Estimated annual revenue of the company/client")
    @ManyToOne
    @JoinColumn(nullable = false, name = "revenue")
    protected ClientRevenue revenue;
    
    /** The pwc vertical. */
    @ApiObjectField(description = "PwC vertical definition")
    @ManyToOne
    @JoinColumn(nullable = false, name = "vertical")
    protected Vertical vertical;
    
    /** The industry. */
    @ManyToOne
    @JoinColumn(nullable = false, name = "industry")
    protected Industry industry;
    
    @ManyToOne
    @JoinColumn(nullable = false, name = "territory_id")
    protected Territory territory;
    
    /** The sub industry. */
    @ManyToOne
    @JoinColumn(nullable = false, name = "sub_ind")
    protected SubIndustry subIndustry;
    
    /** The employee number. */
    @ApiObjectField(description = "Estimated amount of employees of the company/client")
    @ManyToOne
    @JoinColumn(nullable = false, name = "emp_nmb")
    protected EmployeeNumber employeeNumber;
    
    /** The location. */
    @ApiObjectField(description = "Where the company/client is located")
    protected String location;
    
    /** The domain list. */
    @Cascade(value = CascadeType.ALL)
    @OneToMany(fetch = FetchType.LAZY)
    private List<EmailDomain> domainList;
    

    }
    当更改上述表user 中的project_id 时,将user或者project实体返回
    return new ResultMessage(1, "Successfully!", project);
    则会报无法解析client下相关实体的问题,
    Could not write Json: failed to lazily initialize a collection of role:...could not initialize proxy - no session: 接下来就是错误栈信息,将project --> client -->vertical .....
    解决方式是
    1.显示的再查询project一次,则可以正确解析
    2.不返回project,返回null

    补充,今天我更改了一个实体,对实体的子列表进行排序,直接造成了数据库更新。解决方法将子列表放到新的对象里面进行处理。
    List<ImpactSubCategory> impactSubCategory = new ArrayList<>();
    if (CollectionUtils.isNotEmpty(ic.getImpactSubCategory())) {
    impactSubCategory.addAll(ic.getImpactSubCategory());
    //don't modify entity values directly otherwise it will excute database update
    impactSubCategory.sort((ImpactSubCategory o1, ImpactSubCategory o2) -> {
    return o1.getValue().compareTo(o2.getValue());
    });
    }

    相关文章

      网友评论

          本文标题:Spring JPA自动更新诡异现象

          本文链接:https://www.haomeiwen.com/subject/elbvfhtx.html