Java CriteriaBuilder Join - 无法解决或不是字段
Java CriteriaBuilder Join - cannot be solved or is not a field
我正在尝试使用 CriteriaBuilder
中的联接执行 select,但我在 Eclipse 中遇到此错误。我该如何解决?
Hibernate version: hibernate-jpa-2.0-api<br />
Java Version: 1.8
fonte cannot be solved or is not a field
NotificacaoDao.java
@Stateless
public class NotificacaoDao {
@PersistenceContext(unitName = "PostgreSQLDS")
private EntityManager em;
@EJB
private NotificacaoDao NotificacaoDao;
public List<Notificacao> getResultList(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) throws ApplicationException{
try {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Notificacao> cq = cb.createQuery(Notificacao.class);
Metamodel m = em.getMetamodel();
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(Notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(Notificacao_.fonte); // HERE I'M GETTING THE ERROR
cq.where(NotificacaoDao.getFilterCondition(cb, myObj, filters));
Predicate filterCondition = NotificacaoDao.getFilterCondition(cb, myObj, filters);
filterCondition = cb.and(filterCondition, cb.equal(myObj.get("excluido"), "N"));
cq.where(filterCondition);
if (sortField != null) {
if (sortOrder == SortOrder.ASCENDING) {
cq.orderBy(cb.asc(myObj.get(sortField)));
} else if (sortOrder == SortOrder.DESCENDING) {
cq.orderBy(cb.desc(myObj.get(sortField)));
}
}
return em.createQuery(cq).setFirstResult(first).setMaxResults(pageSize).getResultList();
} catch(Exception e) {
throw new ApplicationException("myException", e);
}
}
Notificacao.java
@Entity
@Table(name = "tb_notificacao", schema = "indicadores")
@NamedQuery(name = "Notificacao.findAll", query = "SELECT n FROM Notificacao n")
@FilterDef(name="notificacaoNaoExcluido", defaultCondition="excluido = 'N'")
public class Notificacao implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "tb_notificacao_codnotificacao_seq", sequenceName = "TB_NOTIFICACAO_CODNOTIFICACAO_SEQ", schema = "indicadores", allocationSize = 1)
@GeneratedValue(generator = "tb_notificacao_codnotificacao_seq")
@Column(name = "codnotificacao", nullable = false)
private Integer codnotificacao;
private String descricao;
private String excluido;
private String nome;
// bi-directional many-to-one association to CargaNotificacao
@OneToMany(mappedBy = "notificacao")
private List<CargaNotificacao> cargaNotificacoes;
// bi-directional many-to-one association to Fonte
@Inject
@ManyToOne
@JoinColumn(name = "codfonte")
private Fonte fonte;
// bi-directional many-to-one association to UsuarioNotificacao
@OneToMany(mappedBy = "notificacao")
@Filter(name="usuarioNaoExcluido", condition="excluido = 'N'")
private List<UsuarioNotificacao> usuarioNotificacoes;
public Notificacao() {
}
// getters and setters
}
Fonte.java
@Entity
@Table(name = "tb_fonte", schema = "indicadores")
@NamedQuery(name = "Fonte.findAll", query = "SELECT f FROM Fonte f")
public class Fonte implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "tb_fonte_codfonte_seq", sequenceName = "TB_FONTE_CODFONTE_SEQ", schema = "indicadores", allocationSize = 1)
@GeneratedValue(generator = "tb_fonte_codfonte_seq")
@Column(name = "codfonte", nullable = false)
private Integer codfonte;
private String nome;
// bi-directional many-to-one association to Indicador
@OneToMany(mappedBy = "fonte")
@Filter(name="indicadorNaoExcluido", condition="excluido = 'N'")
private List<Indicador> indicadores;
// bi-directional many-to-one association to Notificacao
@OneToMany(mappedBy = "fonte")
@Filter(name="notificacaoNaoExcluido", condition="excluido = 'N'")
private List<Notificacao> notificacoes;
public Fonte() {
}
// getters and setters
}
嗯,在元模型上,基本上可以使用三种方法:
- 使用基于IDE 的元模型生成工具
- 使用静态规范元模型类
- 使用 em.getMetamodel() API 即 您正在使用的 .
我建议您使用的解决方案更接近您在第 3 点所做的事情。
第3点解法:
替换以下代码:
Metamodel m = em.getMetamodel();
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(Notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(Notificacao_.fonte); // HERE I'M GETTING THE ERROR
使用新代码:
Metamodel m = em.getMetamodel();
EntityType<Notificacao> notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(notificacao_.getSingularAttribute("fonte",Fonte.class));
第 1 点和第 2 点解决方案
请注意 Notificacao_ 必须是 class 静态的或生成的,并且绝不能是 em.getMetamodel() 的实例。另请注意,在 Notificacao_ 之前,您的情况是变量而不是 class,如图所示:
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
如果您需要更多信息,请告诉我。
我正在尝试使用 CriteriaBuilder
中的联接执行 select,但我在 Eclipse 中遇到此错误。我该如何解决?
Hibernate version: hibernate-jpa-2.0-api<br />
Java Version: 1.8
fonte cannot be solved or is not a field
NotificacaoDao.java
@Stateless
public class NotificacaoDao {
@PersistenceContext(unitName = "PostgreSQLDS")
private EntityManager em;
@EJB
private NotificacaoDao NotificacaoDao;
public List<Notificacao> getResultList(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) throws ApplicationException{
try {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Notificacao> cq = cb.createQuery(Notificacao.class);
Metamodel m = em.getMetamodel();
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(Notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(Notificacao_.fonte); // HERE I'M GETTING THE ERROR
cq.where(NotificacaoDao.getFilterCondition(cb, myObj, filters));
Predicate filterCondition = NotificacaoDao.getFilterCondition(cb, myObj, filters);
filterCondition = cb.and(filterCondition, cb.equal(myObj.get("excluido"), "N"));
cq.where(filterCondition);
if (sortField != null) {
if (sortOrder == SortOrder.ASCENDING) {
cq.orderBy(cb.asc(myObj.get(sortField)));
} else if (sortOrder == SortOrder.DESCENDING) {
cq.orderBy(cb.desc(myObj.get(sortField)));
}
}
return em.createQuery(cq).setFirstResult(first).setMaxResults(pageSize).getResultList();
} catch(Exception e) {
throw new ApplicationException("myException", e);
}
}
Notificacao.java
@Entity
@Table(name = "tb_notificacao", schema = "indicadores")
@NamedQuery(name = "Notificacao.findAll", query = "SELECT n FROM Notificacao n")
@FilterDef(name="notificacaoNaoExcluido", defaultCondition="excluido = 'N'")
public class Notificacao implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "tb_notificacao_codnotificacao_seq", sequenceName = "TB_NOTIFICACAO_CODNOTIFICACAO_SEQ", schema = "indicadores", allocationSize = 1)
@GeneratedValue(generator = "tb_notificacao_codnotificacao_seq")
@Column(name = "codnotificacao", nullable = false)
private Integer codnotificacao;
private String descricao;
private String excluido;
private String nome;
// bi-directional many-to-one association to CargaNotificacao
@OneToMany(mappedBy = "notificacao")
private List<CargaNotificacao> cargaNotificacoes;
// bi-directional many-to-one association to Fonte
@Inject
@ManyToOne
@JoinColumn(name = "codfonte")
private Fonte fonte;
// bi-directional many-to-one association to UsuarioNotificacao
@OneToMany(mappedBy = "notificacao")
@Filter(name="usuarioNaoExcluido", condition="excluido = 'N'")
private List<UsuarioNotificacao> usuarioNotificacoes;
public Notificacao() {
}
// getters and setters
}
Fonte.java
@Entity
@Table(name = "tb_fonte", schema = "indicadores")
@NamedQuery(name = "Fonte.findAll", query = "SELECT f FROM Fonte f")
public class Fonte implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name = "tb_fonte_codfonte_seq", sequenceName = "TB_FONTE_CODFONTE_SEQ", schema = "indicadores", allocationSize = 1)
@GeneratedValue(generator = "tb_fonte_codfonte_seq")
@Column(name = "codfonte", nullable = false)
private Integer codfonte;
private String nome;
// bi-directional many-to-one association to Indicador
@OneToMany(mappedBy = "fonte")
@Filter(name="indicadorNaoExcluido", condition="excluido = 'N'")
private List<Indicador> indicadores;
// bi-directional many-to-one association to Notificacao
@OneToMany(mappedBy = "fonte")
@Filter(name="notificacaoNaoExcluido", condition="excluido = 'N'")
private List<Notificacao> notificacoes;
public Fonte() {
}
// getters and setters
}
嗯,在元模型上,基本上可以使用三种方法:
- 使用基于IDE 的元模型生成工具
- 使用静态规范元模型类
- 使用 em.getMetamodel() API 即 您正在使用的 .
我建议您使用的解决方案更接近您在第 3 点所做的事情。
第3点解法: 替换以下代码:
Metamodel m = em.getMetamodel();
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(Notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(Notificacao_.fonte); // HERE I'M GETTING THE ERROR
使用新代码:
Metamodel m = em.getMetamodel();
EntityType<Notificacao> notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(notificacao_.getSingularAttribute("fonte",Fonte.class));
第 1 点和第 2 点解决方案 请注意 Notificacao_ 必须是 class 静态的或生成的,并且绝不能是 em.getMetamodel() 的实例。另请注意,在 Notificacao_ 之前,您的情况是变量而不是 class,如图所示:
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
如果您需要更多信息,请告诉我。