欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-13 15:59:41
...

最近在项目中发现在事务中只执行了查询操作,开启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>