2015-10-24 61 views
1

我有一個非常奇怪的行爲在我的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」:

enter image description here

另一個奇怪的事實是,本次檢查查詢工作正常,當我切換到MySQL。這種奇怪的行爲僅在使用H2 DB時纔會發生。

回答

0

看來,這種行爲是由裝飾()我在表演到rfCoil字符串值造成的:

@Override 
public Boolean checkDicomStudyRfCoilExistForStudy(String studyInstanceUID, String rfCoil) { 
    ... 
    query.setParameter("rfCoil", rfCoil.trim()); 
    ... 

然而在MySQL中,這是不會發生