这是我的查看数据:
30.0 120.0 1500.0 16
30.0 120.0 4000.0 16
30.0 140.0 1500.0 16
30.0 140.0 4000.0 16
35.0 130.0 2750.0 18
40.0 120.0 1500.0 16
40.0 120.0 4000.0 16
40.0 140.0 1500.0 16
40.0 140.0 4000.0 16
这是我的代码:
public List<Duplicate> getData() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DXSorterPU");
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin();
List<Duplicate> result = entityManager.createQuery("SELECT d FROM Duplicate d").getResultList();
for (Duplicate d : result) {
System.out.println(d.getF1()+" " +d.getF3()+" "+ d.getF4()+" "+ d.getResult()) ;
}
entityManager.getTransaction().commit();
entityManager.close();
return result;
}
这是我通过上面的代码获得的数据:
30.0 120.0 1500.0 16
30.0 120.0 1500.0 16
30.0 120.0 1500.0 16
30.0 120.0 1500.0 16
35.0 130.0 2750.0 18
40.0 120.0 1500.0 16
40.0 120.0 1500.0 16
40.0 120.0 1500.0 16
40.0 120.0 1500.0 16
为什么结果不同?请帮助我。
这是我的重复班:
package dxsorter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
@Entity
@Table(name = "DUPLICATE")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Duplicate.findAll", query = "SELECT d FROM Duplicate d")
, @NamedQuery(name = "Duplicate.findByF1", query = "SELECT d FROM Duplicate d WHERE d.f1 = :f1")
, @NamedQuery(name = "Duplicate.findByF3", query = "SELECT d FROM Duplicate d WHERE d.f3 = :f3")
, @NamedQuery(name = "Duplicate.findByF4", query = "SELECT d FROM Duplicate d WHERE d.f4 = :f4")
, @NamedQuery(name = "Duplicate.findByResult", query = "SELECT d FROM Duplicate d WHERE d.result = :result")})
public class Duplicate implements Serializable {
private static final long serialVersionUID = 1L;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Basic(optional = false)
@Column(name = "F1")
@Id
private BigDecimal f1;
@Basic(optional = false)
@Column(name = "F3")
private BigDecimal f3;
@Basic(optional = false)
@Column(name = "F4")
private BigDecimal f4;
@Basic(optional = false)
@Column(name = "RESULT")
private int result;
public Duplicate() {
}
public BigDecimal getF1() {
return f1;
}
public void setF1(BigDecimal f1) {
this.f1 = f1;
}
public BigDecimal getF3() {
return f3;
}
public void setF3(BigDecimal f3) {
this.f3 = f3;
}
public BigDecimal getF4() {
return f4;
}
public void setF4(BigDecimal f4) {
this.f4 = f4;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public List<Duplicate> getData() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DXSorterPU");
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin();
List<Duplicate> result = entityManager.createQuery("SELECT d FROM Duplicate d").getResultList();
for (Duplicate d : result) {
System.out.println(d.getF1()+" " +d.getF3()+" "+ d.getF4()+" "+ d.getResult()) ;
}
entityManager.getTransaction().commit();
entityManager.close();
return result;
}
}
答案 0 :(得分:2)
您的问题是,用@Id
(F1)注释的列在视图中不是唯一的。
您的JPA提供程序(例如,休眠)假定F1
的值在视图中是唯一的。
这就是执行查询时发生的事情:
让我们说,获取的第一行是
30.0 120.0 1500.0 16
。
您的JPA提供程序将此行与ID 30.0
(F1列的值)相关联。
可以说,提取的下一行是30.0 120.0 4000.0 16
。现在,我们可以看到该行与第一行不同。但是您的JPA提供者不知道这一点。提供程序看到的是此行的id
的值为30
。因为他已经获取了具有该ID的行(并将其存储在会话/缓存中),所以他认为该行是同一行。因此,他没有在第二行中创建新对象,而是在第一行中放置了相同的对象。
为了解决此问题,您应该创建一个真实的id
列(在视图中将具有唯一值)或使用原始SQL查询。
向视图添加ID列
MySQL:
您可以使用mysql中的UUID()
函数向视图添加唯一标识符。 here对此进行了说明。
使用UUID,您的选择应如下所示:
SELECT UUID() as ID, FACTORS.F1, FACTORS.F3, FACTORS.F4, COUNT() AS RESULT FROM APP.FACTORS GROUP BY FACTORS.F1, FACTORS.F3, FACTORS.F4 HAVING COUNT() > 1
我在rextester上创建了一个简单的例子。您可以检出here。
德比:
在德比中,您可以使用ROW_NUMBER()
函数。
您的选择应如下所示:
SELECT ROW_NUMBER() OVER () as ID, FACTORS.F1, FACTORS.F3, FACTORS.F4, COUNT() AS RESULT FROM APP.FACTORS GROUP BY FACTORS.F1, FACTORS.F3, FACTORS.F4 HAVING COUNT() > 1