select 查询的 H2 数据库问题 - 结果错误
H2 database issue with select query - wrong results
我的 h2 数据库有一个非常奇怪的行为,即对特定数据库 table 进行简单的 select 查询。同样的查询在 MySQL 上运行良好,但是如果我将我的应用程序的底层数据库切换到 H2,它会 returns 错误的结果(应用程序可以 运行 在 MySQL 和 H2 数据库上).
我有第二个几乎相同的查询,它运行良好,所以我将两个查询都发布在这里以便更好地理解。
有两个table:"StudyProtocolNames"和"StudyRfCoils"与table"StudyDetails"有N-1关系(StudyDetails.stId主键是 StudyProtocolNames 和 StudyRfCoils 上的外键)。
这是父级 table class "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" classes:
@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 的记录。如果已经有这样一条记录,这个方法returns 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" table 进行完全相同的检查(不同的列相同的逻辑):
@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;
}
table StudyProtocolNames 的第一个检查查询工作正常,如果记录具有相同的 "studyInstanceUID" 和 "protocolName" 那么它 returns 为真。
然而第二个查询总是returns FALSE。它无法找到具有相同 "studyInstanceUID" 和 "rfCoil" 的现有记录。所以我在我的数据库 table 中结束,其中包含多个记录,列 "studyInstanceUID" 和 "rfCoil":
的值相同
另一个奇怪的事实是,当我切换到 MySQL 时,第二个检查查询工作正常。只有在使用 H2 DB 时才会发生这种奇怪的行为。
似乎此行为是由我对 rfCoil 字符串值执行的 trim() 引起的:
@Override
public Boolean checkDicomStudyRfCoilExistForStudy(String studyInstanceUID, String rfCoil) {
...
query.setParameter("rfCoil", rfCoil.trim());
...
然而在MySQL这并没有发生
我的 h2 数据库有一个非常奇怪的行为,即对特定数据库 table 进行简单的 select 查询。同样的查询在 MySQL 上运行良好,但是如果我将我的应用程序的底层数据库切换到 H2,它会 returns 错误的结果(应用程序可以 运行 在 MySQL 和 H2 数据库上).
我有第二个几乎相同的查询,它运行良好,所以我将两个查询都发布在这里以便更好地理解。
有两个table:"StudyProtocolNames"和"StudyRfCoils"与table"StudyDetails"有N-1关系(StudyDetails.stId主键是 StudyProtocolNames 和 StudyRfCoils 上的外键)。
这是父级 table class "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" classes:
@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 的记录。如果已经有这样一条记录,这个方法returns 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" table 进行完全相同的检查(不同的列相同的逻辑):
@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;
}
table StudyProtocolNames 的第一个检查查询工作正常,如果记录具有相同的 "studyInstanceUID" 和 "protocolName" 那么它 returns 为真。
然而第二个查询总是returns FALSE。它无法找到具有相同 "studyInstanceUID" 和 "rfCoil" 的现有记录。所以我在我的数据库 table 中结束,其中包含多个记录,列 "studyInstanceUID" 和 "rfCoil":
的值相同另一个奇怪的事实是,当我切换到 MySQL 时,第二个检查查询工作正常。只有在使用 H2 DB 时才会发生这种奇怪的行为。
似乎此行为是由我对 rfCoil 字符串值执行的 trim() 引起的:
@Override
public Boolean checkDicomStudyRfCoilExistForStudy(String studyInstanceUID, String rfCoil) {
...
query.setParameter("rfCoil", rfCoil.trim());
...
然而在MySQL这并没有发生