关于spring-data-jpa:spring-data-jpa-关于父实体保存而子实体存在id会进行多余查询的问题
先对题目给个具体的解释,其实是个级联保留的问题,我上一段实体代码 @Table(name="open_app_user")@Entitypublic class OpenAppUser extends BaseEntity implements UserDetails { /** * 所属利用id */ @ApiModelProperty(value="所属利用id") @ManyToOne @JoinColumn(name = "app_id") //private Integer appId; private OpenApp openApp; // ...}@Table(name="open_app")@Entitypublic class OpenApp extends BaseEntity { // ...}这里有两个实体,一个是父实体OpenAppUser,一个是子实体OpenApp,我遇到的一个问题是,我须要保留OpenAppUser,然而须要一个OpenApp对象,我在前端传了一个id映射到OpenApp里了,然而在保留的时候appUserRepository.save(appUser);因为openApp是一个瞬态实体,会报找不到app_id异样(这是我app_user表里的app_id字段)。 起初我试了一下在save之前,我先应用appRepository.findById(appId);把openApp对象通过查问的形式变成了长久化实体,再去save(appUser);这时候是能够的。 不过看打印的sql日志,这种保留形式,在这之前都要进行查问,这里是依赖了利用,可能还有其余的,比方用户所属部门等等,那样的效率就低了,我想着在我保留的时候,我只须要传其余依赖的id就行了,不须要一个残缺的对象,我就开始看hibernate官网文档,发现了entityManager有个getReference(id)办法能够返回一个实体代理,获取这个实体代理的时候并不一定就会查询数据库。 而后我就发现spring data jpa的实现类里JpaRepository的getById(id)就是调用的entityManager.getReference(id),而后把appRepository.findById(appId)改成appRepository.getById(appId),再去看sql打印的时候,这次就没有再查问了,而是间接用的openApp代理实体里的id属性(我也只有这个属性,是通过前端传的)。这个插入效率就高很多了,一下子优化了查问。 spring data jpa 对于存在id保留,不存在id则新增的解决,有个AbstractPersistable类,能够通过设置它来实现,spring外面是通过判断id是不是null来走entityManager.persist还是merg的。