首页 > 解决方案 > JPA / Hibernate 偶尔会为关系数据运行完全错误的 SQL

问题描述

这让我失去了想法。

所以我有一个类,它是一个名为ServiceForm的数据模型类,它有大约 15 个与相关数据表的连接,一对多和一对一连接的组合。

我调用存储库 (ServiceFormRepository) 来检索单个 ServiceForm 记录。Hibernate 然后处理加载这个类的所有相关数据。

98% 的时间都可以正常工作,我看到休眠日志运行对 ServiceForm 的查询,然后对每个相关表进行查询(不是我所知道的最有效的方式)。

但是偶尔它会开始为相关的数据检索运行错误的查询。日志将显示它将重复运行例如第 3 个相关数据查询,而不是运行第 4、5、6 个查询。

这通常会继续发生,直到我重新启动服务器。重新启动服务器后重试相同的记录将再次完美运行。

正确日志示例- 您可以在每一行看到不同的查询,因为它正在检索不同的相关数据。

错误日志示例- 现在您可以看到它多次运行第三个查询,它不会更改为其他关系的 SQL。

发生这种情况时,它无法检索某些关系的数据。

重新启动 spring-boot 服务器是我发现的唯一解决方案,可以让事情再次稳定运行。已经看到这整整一周没有发生,然后在一天内发生多次。

显示调用以检索 ServiceForm 记录的代码片段。

@Autowired
ServiceFormService serviceFormService;
...
...
// Line below is inside a method where call is made to the ServiceFormService to retrieve the data.
ServiceForm serviceForm = serviceFormService.getServiceFormBySubmissionId(formSubmission.getSubmissionId());

调用存储库的 ServiceFormService 类中的代码片段。

@Service
public class ServiceFormService {

    @Autowired
    ServiceFormRepository serviceFormRepo;

    public ServiceForm getServiceFormBySubmissionId(String submissionId) {

        return serviceFormRepo.getBySubmissionId(submissionId);
    }

}

显示 ServiceForm 类中连接的代码片段。

@Entity
@Table(name = "ServiceForm")
public class ServiceForm implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id", nullable = false, unique = true)
   private Integer id;

   // Needs unique property when joining tables with non-PK associations otherwise hibernate throws exception cannot be cast to java.io.Serializable.
   @Column(name = "submissionId", nullable = true, unique = true)
   private String submissionId;

...
...


   @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumns({
        @JoinColumn(name = "submissionId", referencedColumnName = "submissionId", insertable = false, updatable = false)
   })
   private CustomerDetails customerDetails;

   @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumns({
        @JoinColumn(name = "submissionId", referencedColumnName = "submissionId", insertable = false, updatable = false)
   })
   private Jsea jsea;

   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumns({
        @JoinColumn(name = "submissionId", referencedColumnName = "submissionId")
   })
   private List<InverterInspection> inverterInspections = new ArrayList<>();

   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumns({
        @JoinColumn(name = "submissionId", referencedColumnName = "submissionId", insertable = false, updatable = false)
   })
   private Set<SwitchBoard> switchBoards = new LinkedHashSet<>();

...
...

   @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumns({
        @JoinColumn(name = "submissionId", referencedColumnName = "submissionId", insertable = false, updatable = false)
   })
   private CompletionNotes completionNotes;

   @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumns({
        @JoinColumn(name = "submissionId", referencedColumnName = "submissionId", insertable = false, updatable = false)
   })
   private Compliance compliance;

}

我无法将其缩小为代码问题或某种服务器问题,因此欢迎提出任何建议。

已经开始怀疑这是否可能是与数据库连接相关的问题。

标签: javaspring-boothibernatejpa

解决方案


推荐阅读