hibernate只有查询操作,实际却执行了更新语句

在使用Hibernate框架时,若实体类中的值对象未覆盖equals和hashcode方法,可能导致意外的数据库更新操作。本文通过具体案例,阐述了在SpringBoot项目中,由于值对象未覆盖equals和hashcode,Hibernate误判对象不等,进而执行了不必要的删除和插入操作,增加了数据库负担。文章还提供了正确的equals和hashcode实现方式,以及如何在SpringBoot中配置日志以查看Hibernate SQL语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在项目中发现在事务中只执行了查询操作,开启sql debug打印却发现有更新语句。经过排查发现是实体中包含的值对象没有覆盖equals和hashcode操作,怀疑hibernate在用默认的equals进行比较的时候发现对象不等,所以执行了删除操作,然后再执行插入操作。

实体对象:

@Getter
@Setter
@ToString
@Entity
public class Person extends AbstractPersistable {
    @Column
    private String name;
    @ElementCollection(targetClass = Phone.class)
    @CollectionTable
    private Set<Phone> phones;
}

值对象:

@Getter
@Setter
@ToString
@Embeddable
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "number")
public class Phone implements Serializable {
    @Column
    private String number;
}

注意要覆盖equals和hashcode。否则debug日志如下:

Hibernate: select person0_.id as id1_19_, person0_.version as version2_19_, person0_.name as name3_19_ from person person0_ where person0_.name=?
Hibernate: select phones0_.person_id as person_i1_20_0_, phones0_.number as number2_20_0_ from person_phones phones0_ where phones0_.person_id=?
Person(name=333, phones=[Phone(number=34567), Phone(number=3456)])
Hibernate: update person set version=?, name=? where id=? and version=?
Hibernate: delete from person_phones where person_id=?
Hibernate: insert into person_phones (person_id, number) values (?, ?)
Hibernate: insert into person_phones (person_id, number) values (?, ?)

附spring boot开启hibernate sql打印和参数打印方法:

resources下加入logback-spring.xml,其中的内容如下:

<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="org.hibernate.engine.QueryParameters" level="DEBUG"/>
    <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG"/>
    <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
    <logger name="org.hibernate.SQL" level="DEBUG"/>
</configuration>

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值