postgresql - JPA/hibernate/PostgresDB 和 Vaadin 8 : SQL select query to get data from inherited tables and show in Vaadin grid

标签 postgresql hibernate jpa-2.0 vaadin8

我将 Vaadin 8 与 Java/hibernate/JPA 和 postgres 数据库一起使用。我想从不同的表中获取数据到我的 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 
} 

负控制.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;

}

结构数据.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;

}

仅从 Probe 表中选择数据效果很好,数据显示在我的 Vaadin 网格中:

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

在 View 类中:

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

但我还需要显示来自 StructureData 的数据和来自 NegativeControl 的特殊名称。我尝试了许多不同的 select 语句,但总是出现 hibernate 错误。一些错误版本(只是为了从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)

我正在寻找有效的选择语句和 Vaadin grid.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 网格问题。我不知道如何直接设置不是 Probe 列而是 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");

但是 Probe::getStructureData 给出了错误“这个表达式的目标类型必须是一个函数式接口(interface)”。

我希望有人能帮我解决这个问题。谢谢!

最佳答案

我终于知道怎么做了。我发布答案以防其他人有同样的问题需要解决。

如上面的编辑所述,查询是:

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 是我从上述数据库查询中获得的探测器列表。

关于postgresql - JPA/hibernate/PostgresDB 和 Vaadin 8 : SQL select query to get data from inherited tables and show in Vaadin grid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46489747/

相关文章:

postgresql - 如何在 docker compose 中为 postgres 使用音量?

sql - Hibernate 性能调整

java - 没有外键但有反向外键的 hibernate 多对一关系

google-app-engine - 按键查询数据存储时得到空值

java - 从现有数据库生成 JPA 2 实体

java - 如何避免使用 JPA 注释的循环引用?

postgresql - 使用 psql\copy 导入带有时间戳列 (dd.mm.yyyy hh.mm.ss) 的 .csv

postgresql - 在 PostgreSQL 中按二元运算符分组

sql - Postgres : how to call a function that returns a table and pass params from a query

java - 找不到部署 "war"的子部署 "ear"中命名的持久性单元