我有一個非常奇怪的行爲在我的h2數據庫與特定的數據庫表上的簡單選擇查詢。這同樣的查詢與MySQL工作正常,但是,如果我切換我的應用程序的底層數據庫爲H2它返回錯誤的結果(應用程序可以運行在MySQL上也如H2 H2)。H2數據庫問題與選擇查詢 - 錯誤的結果
我有第二個幾乎相同的查詢工作正常,所以我張貼在這裏都更好的理解。
有兩個表:「StudyProtocolNames」和「StudyRfCoils」,它們與表StudyDetails具有N-1關係(StudyDetails.stId主鍵是StudyProtocolNames和StudyRfCoils上的外鍵)。
這裏是父表類 「StudyDetails」:
@Entity
@Table(name="StudyDetails",
uniqueConstraints = @UniqueConstraint(columnNames = "StudyInstanceUID"))
public class StudyDetails implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name="StId", unique = true, nullable = false)
private Long stId;
@Column(name="StudyInstanceUID", unique=true, nullable = false)
private String studyInstanceUID;
@Column(name="SoapResponse")
private int soapResponse;
@Column(name="PatientName")
private String patientName;
@Column(name="RfCoil", nullable = false)
private String rfCoil;
@Column(name="ProtocolName", nullable = false)
private String protocolName;
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "studyDetails", cascade = CascadeType.ALL)
private Set<StudyProtocolNames> studyProtocolNames = new HashSet<>(0);
@OneToMany(fetch = FetchType.LAZY, mappedBy = "studyDetails", cascade = CascadeType.ALL)
private Set<StudyRfCoils> studyRfCoils = new HashSet<>(0);
...
}
,這裏是 「StudyProtocolNames」 和 「StudyRfCoils」 類:
@Entity
@Table(name="StudyProtocolNames")
public class StudyProtocolNames implements Serializable {
private static long serialVersionUID = -298254562330274106L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "PnId", unique = true, nullable = false)
private Long pnId;
@Column(name="StudyInstanceUID")
private String studyInstanceUID;
@Column(name="ProtocolName", nullable = false)
private String protocolName;
@ManyToOne
@JoinColumn(name = "StId", referencedColumnName="StId")
private StudyDetails studyDetails;
...
}
...
@Entity
@Table(name="StudyRfCoils")
public class StudyRfCoils implements Serializable {
private static long serialVersionUID = -298254562330274106L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "RfcId", unique = true, nullable = false)
private Long rfcId;
@Column(name="StudyInstanceUID")
private String studyInstanceUID;
@Column(name="RfCoil", nullable = false)
private String rfCoil;
@ManyToOne
@JoinColumn(name = "StId", referencedColumnName="StId")
private StudyDetails studyDetails;
...
}
在我申請的某個時候,在向「StudyProtocolNames」插入新記錄之前,我檢查是否已經存在與studyInstanceUID和protocolName相同的記錄。如果已經有這樣的記錄,則此方法返回true。
@Override
public Boolean checkDicomStudyProtocolNameExistForStudy(String studyInstanceUID, String protocolName) {
Boolean status = false;
List<String> results=new ArrayList<>();
Session s=HibernateUtil.openSession();
s.beginTransaction();
String hql = "FROM StudyProtocolNames E WHERE E.studyInstanceUID = :studyInstanceUID AND E.protocolName = :protocolName";
Query query = s.createQuery(hql);
query.setParameter("protocolName", protocolName.trim());
query.setParameter("studyInstanceUID", studyInstanceUID);
results = query.list();
s.getTransaction().commit();
s.close();
log.info(results.size() + " Records found for study in checkDicomStudyProtocolNameExistForStudy: " + studyInstanceUID + " and protocolName" + protocolName);
if(results.isEmpty()) {
status = false;
} else {
status = true;
}
return status;
}
我做的「StudyRfCoils」表(不同的列相同的邏輯)完全相同的檢查:
@Override
public Boolean checkDicomStudyRfCoilExistForStudy(String studyInstanceUID, String rfCoil) {
Boolean status = false;
List<String> results=new ArrayList<>();
Session s=HibernateUtil.openSession();
s.beginTransaction();
String hql = "FROM StudyRfCoils E WHERE E.studyInstanceUID = :studyInstanceUID AND E.rfCoil = :rfCoil";
Query query = s.createQuery(hql);
query.setParameter("rfCoil", rfCoil.trim());
query.setParameter("studyInstanceUID", studyInstanceUID);
results = query.list();
s.getTransaction().commit();
s.close();
log.info(results.size() + " Records found for study in checkDicomStudyRfCoilExistForStudy: " + studyInstanceUID + " and rfCoil: " + rfCoil);
if(results.isEmpty()) {
status = false;
} else {
status = true;
}
return status;
}
爲表StudyProtocolNames首先檢查查詢工作正常,如果用相同的記錄「 studyInstanceUID「和」protocolName「,那麼它返回true。
然而第二個查詢總是返回FALSE。它不能使用相同的「studyInstanceUID」和「rfCoil」定位已有的記錄。所以我最終在我的數據庫表具有相同值的多個記錄列「studyInstanceUID」和「rfCoil」:
另一個奇怪的事實是,本次檢查查詢工作正常,當我切換到MySQL。這種奇怪的行爲僅在使用H2 DB時纔會發生。