Spring Boot 2.7迁移至3.0后Data save方法失效求助
问题场景
将Spring Boot从2.7.17升级至3.0.5,同步把Hibernate从5.x升级到6.2.0.Final后,项目中Order实体通过@ElementCollection关联的OrderDetails可嵌入类,其@Parent注解标注的Order引用在调用OrderRepository.save()后变为null,而迁移前该逻辑正常。
相关核心代码如下:
Order实体类
@Entity @Table(name = "ORDER") @NoArgsConstructor(access = AccessLevel.PRIVATE) @ToString @EqualsAndHashCode(onlyExplicitlyIncluded = true) @NamedEntityGraph( name = "Order.orderDetails", attributeNodes = { @NamedAttributeNode("orderDetails") } ) public class Order { @Id @Column(nullable = false) @EqualsAndHashCode.Include private String orderId; @ElementCollection @CollectionTable( name = "SITE_SPECIFIC_DETAILS_COMMAND", joinColumns = @JoinColumn(name = "orderId") ) private Set<OrderDetails> orderDetails; // 其余代码省略 }
OrderDetails可嵌入类
@Embeddable @NoArgsConstructor @AllArgsConstructor @Builder(setterPrefix = "with") @EqualsAndHashCode(onlyExplicitlyIncluded = true) @Data public class OrderDetails { @ToString.Exclude @Parent @EqualsAndHashCode.Include private Order parent; @Type(JsonType.class) @Column(columnDefinition = "jsonb") private OrderData data; // 其余代码省略 }
Repository定义
public interface OrderRepository extends Repository<Order, String> { @EntityGraph(attributePaths = {"orderDetails"}) Order save(Order order); }
排查方向
检查Hibernate 6对
@Parent的处理变更
Hibernate 6对可嵌入类的@Parent注解维护逻辑有调整,5.x版本中可能自动将父实体注入到可嵌入类的parent字段,但6.x可能不再自动处理。可以尝试在保存Order前,手动遍历orderDetails集合,为每个OrderDetails设置parent引用,再执行save操作验证是否恢复正常。验证
@EntityGraph的影响
当前save方法上标注了@EntityGraph(attributePaths = {"orderDetails"}),Hibernate 6中实体图的加载逻辑可能有变化,导致保存后关联对象的parent引用未被正确初始化。尝试移除该注解,测试save后parent引用是否正常,再逐步排查实体图配置问题。排查Lombok注解兼容性
OrderDetails使用了@Data、@Builder等Lombok注解,Hibernate 6对字段访问、构造方法的兼容性要求更严格:- 尝试移除
@Data,手动编写parent字段的getter/setter,避免Lombok生成的方法干扰Hibernate的字段注入; - 调整
@NoArgsConstructor的访问级别为public,Hibernate 6可能要求可嵌入类的无参构造方法必须是公开的; - 检查
@Builder的配置,确保withParent()方法能正确设置parent引用,且未被Lombok的其他逻辑覆盖。
- 尝试移除
检查持久化上下文的状态
在save前后通过EntityManager打印持久化上下文的实体状态,查看Order与OrderDetails的关联关系在Hibernate中的维护情况。也可以尝试在save后调用entityManager.refresh(order),验证是否能恢复parent引用,判断是否是Hibernate未及时初始化关联。验证数据库映射与SQL生成
确认SITE_SPECIFIC_DETAILS_COMMAND表的orderId外键字段映射正确,查看Hibernate生成的SQL语句,确认保存OrderDetails时是否正确关联了orderId。如果外键映射异常,Hibernate无法通过外键反向关联parent引用,也会导致该问题。
内容的提问来源于stack exchange,提问作者MarcinS

