2017-09-29 41 views
0

我使用Vaadin 8与Java继承自表和数据显示/休眠/ JPA和Postgres数据库。我想从不同的表格中获取数据到我的Vaadin网格中。相关部分从我的数据库模型如下所示:JPA /休眠/ PostgresDB和Vaadin 8:SQL SELECT查询以获得Vaadin电网

database model

Compound.java样子:

@Entity 
@Table(name = "\"Compound\"") 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING) 
public abstract class Compound { 

@Id 
@GeneratedValue 
@Column(name = "id", nullable = false) 
private UUID id; 

@Column(name = "\"specialName\"", unique = true, nullable = false) 
private String specialName; 

@Column(name = "\"dateAdded\"", nullable = false) 
private LocalDate dateAdded; 

@OneToOne(mappedBy = "compound", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) 
private StructureData structureData; 

//Getter and setter are omitted here 

} 

Probe.java类:

@Entity(name = "\"Probe\"") 
@Table(name = "\"Probe\"") 
@PrimaryKeyJoinColumn(name = "\"compoundId\"") 
@DiscriminatorValue(value = "probe") 
public class Probe extends Compound { 

@Column(name = "\"targetProteinFamily\"", length = 150, nullable = false) 
private String targetProteinFamily; 

@Column(name = "\"probeClass\"", length = 150, nullable = false) 
private String probeClass; 

@OneToMany(mappedBy = "probe", cascade = CascadeType.ALL, orphanRemoval = true) 
private List<NegativeControl> controls; 

    //Getter and setter are omitted 
} 

NegativeControl.java

@Entity(name = "\"NegativeControl\"") 
@Table(name = "\"NegativeControl\"") 
@PrimaryKeyJoinColumn(name = "\"compoundId\"") 
@DiscriminatorValue(value = "control") 
public class NegativeControl extends Compound { 

@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name="\"probeId\"") 
private Probe probe; 

} 

StructureData.java

@Entity(name = "\"StructureData\"") 
@Table(name = "\"StructureData\"") 
public class StructureData { 

@Id 
private UUID id; 

@Column(name = "\"smilesCode\"", columnDefinition = "TEXT") 
private String smilesCode; 

@Column(name = "\"sdFileName\"", length = 255) 
private String sdFileName; 

@OneToOne(fetch = FetchType.LAZY) 
@MapsId 
private Compound compound; 

} 

的选择只能从探测表工作正常,数据显示在我的Vaadin网格中的数据:

List<Probe> allProbes = entityManager.createQuery("select p from " + Probe.class.getName() + " p").getResultList(); 

并在视图类:

grid.setColumns("specialName", "probeClass", "targetProteinFamily"); 

但我也需要显示来自StructureData数据,并从NegativeControl特殊的名字。我尝试了很多不同的select语句,但我总是得到一个休眠错误。有一些错误的版本(只是为了让从StructureData数据),如下所示:

List<Probe> allProbes = entityManager.createQuery("select p , s from " + Probe.class.getName() + " p, " + StructureData.class.getName() + " s where type(p) = probe and Compound.id = s.compound_id").getResultList(); 
List<Probe> allProbes = entityManager.createQuery("select p , s from " + Probe.class.getName() + " p, " + StructureData.class.getName() + " s where type(p) = probe").getResultList(); 

为第一选择的错误是:

SEVERE: 
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: ''Compound'.id' [select p , s from sgc.chemprobesapp.core.model.Probe p, sgc.chemprobesapp.core.model.StructureData s where type(p) = probe and Compound.id = s.compound_id] 
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:131) 

我找工作的SELECT语句和Vaadin电网.setColumns代码。

谢谢你的帮助!

编辑: 我解决我的问题的SQL语句组成部分。以下查询获取所需的数据:

List<Probe> allProbes = entityManager 
      .createQuery("select p from sgc.chemprobesapp.core.model.Probe p " 
        + "left join fetch p.controls c left join fetch p.structureData s", Probe.class) 
      .getResultList(); 

但我的第二部分是Vaadin8网格问题。我不知道如何直接设置不是探测列而是StructureData列的所需列。

grid.setColumns("specialName", "probeClass", "targetProteinFamily", "structureData.sdFileName"); 

这似乎工作。不过,我想用我的字幕设置的栏目,如

grid.addColumn(Probe::getSpecialName).setCaption("Name"); 
grid.addColumn(Probe::getTargetProteinFamily).setCaption("Target protein family"); 
grid.addColumn(Probe::getProbeClass).setCaption("Probe class"); 
grid.addColumn(Probe::getStructureData::getSdFileName).setCaption("Structure"); 

但探头:: getStructureData给出了错误“这个表达式的目标类型必须是功能界面”。

我希望有人能帮助我与此有关。谢谢!

回答

0

我终于找到了如何做到这一点。如果别人有同样的问题需要解决,我会发布答案。

如在查询上方编辑指定的是:

List<Probe> allProbes = entityManager 
     .createQuery("select p from sgc.chemprobesapp.core.model.Probe p " 
       + "left join fetch p.controls c left join fetch p.structureData s", Probe.class) 
     .getResultList(); 

从不同数据库表中的数据在一个Vaadin 8网格上的显示可以如下进行:

private Grid<Probe> grid = new Grid<>(Probe.class); 
grid.removeAllColumns(); 
grid.addColumn(probe -> probe.getSpecialName()).setCaption("Name"); 
grid.addColumn(probe -> probe.getTargetProteinFamily()).setCaption("Target protein family"); 
grid.addColumn(probe -> probe.getClass()).setCaption("Class"); 
grid.addColumn(probe -> probe.getStructureData().getSdFileName()).setCaption("Structure"); 
grid.addColumn(probe -> probe.getNegativeControl().get(0).getSpecialName()).setCaption("Negative control"); 
grid.setItems(allProbes); 

我不得不首先删除所有列,因为显示了所有继承表的列。变量allProbes是我从上面的数据库查询中获得的探测列表。