Criteria JPA

Galera estou tentando fazer um consulta nos municipios filtrando pelo id do estado minhas entidades

@Entity
@Table(name = "municipio")
@XmlRootElement
public class Municipio implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_municipio", nullable = false)
    private Integer idMunicipio;

    @Column(name = "municipio", nullable = false, length = 100)
    private String municipio;
    
    @Column(name = "cd_legal", nullable = false, length = 45)
    private String cdLegal;

    @JoinColumn(name = "id_estado", referencedColumnName = "id_estado", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Estado estado;


@Entity
@Table(name = "estado")
@XmlRootElement
public class Estado implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_estado", nullable = false)
    private Integer idEstado;

    @Column(name = "estado", nullable = false, length = 45)
    private String estado;

    @Column(name = "uf", nullable = false, length = 2)
    private String uf;

estou fazendo a seguinte consulta

CriteriaQuery query = getBuilder().createQuery(Municipio.class);
        Root<Municipio> from = query.from(Municipio.class);
        Predicate whereIdEstado = getBuilder().equal(from.get("estado.idEstado"), idEstado);
        query = query.select(from).where(whereIdEstado);
        return this.entityManager.createQuery(query).getResultList();

e estou tendo o seguinte erro como resposta

Caused by: java.lang.IllegalArgumentException: The attribute [estado.idEstado] from the managed type [EntityTypeImpl@15504767:Municipio [ javaType: class com.perfect.smile.entidade.Municipio descriptor: RelationalDescriptor(com.perfect.smile.entidade.Municipio --> [DatabaseTable(municipio)]), mappings: 4]] is not present.
	at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:147)
	at org.eclipse.persistence.internal.jpa.querydef.FromImpl.get(FromImpl.java:312)
	at com.perfect.smile.bo.MunicipioBO.listMunicipio(MunicipioBO.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
	at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
	at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
	at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
	... 78 more

sei que o erro aconteceu por eu ter colocado no where da criteria estado.idEstado mas o que devo colocar ali entaum pois naum possu o idEstado no meu bean municipio e sim apenas o objeto municipio…

o que devo fazer…

[quote=CristianPalmaSola10]Galera estou tentando fazer um consulta nos municipios filtrando pelo id do estado minhas entidades

@Entity
@Table(name = "municipio")
@XmlRootElement
public class Municipio implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_municipio", nullable = false)
    private Integer idMunicipio;

    @Column(name = "municipio", nullable = false, length = 100)
    private String municipio;
    
    @Column(name = "cd_legal", nullable = false, length = 45)
    private String cdLegal;

    @JoinColumn(name = "id_estado", referencedColumnName = "id_estado", nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Estado estado;


@Entity
@Table(name = "estado")
@XmlRootElement
public class Estado implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_estado", nullable = false)
    private Integer idEstado;

    @Column(name = "estado", nullable = false, length = 45)
    private String estado;

    @Column(name = "uf", nullable = false, length = 2)
    private String uf;

estou fazendo a seguinte consulta

CriteriaQuery query = getBuilder().createQuery(Municipio.class);
        Root<Municipio> from = query.from(Municipio.class);
        Predicate whereIdEstado = getBuilder().equal(from.get("estado.idEstado"), idEstado);
        query = query.select(from).where(whereIdEstado);
        return this.entityManager.createQuery(query).getResultList();

e estou tendo o seguinte erro como resposta

Caused by: java.lang.IllegalArgumentException: The attribute [estado.idEstado] from the managed type [EntityTypeImpl@15504767:Municipio [ javaType: class com.perfect.smile.entidade.Municipio descriptor: RelationalDescriptor(com.perfect.smile.entidade.Municipio --> [DatabaseTable(municipio)]), mappings: 4]] is not present.
	at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:147)
	at org.eclipse.persistence.internal.jpa.querydef.FromImpl.get(FromImpl.java:312)
	at com.perfect.smile.bo.MunicipioBO.listMunicipio(MunicipioBO.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
	at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
	at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
	at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
	... 78 more

sei que o erro aconteceu por eu ter colocado no where da criteria estado.idEstado mas o que devo colocar ali entaum pois naum possu o idEstado no meu bean municipio e sim apenas o objeto municipio…

o que devo fazer…[/quote]

Eita que rolo isso ae…pq não tenta só:

SuaSessao.createCriteria(Municipio.class, "municipio")
.createAlias("municipio.estado", "estado")
.add(Restrictions.eq("estado.id", idEstado))
.list();

Ate que eu queria fazer isso mas estou usando jpa puro e essa é a criteria do jpa, por isso é essa confussao toda, concordo com voce amigo é muita coisa para pouco resultado…

mas é assim mesmo…

poderia me ajudar com esse problema ?

[quote=XOOM]Eita que rolo isso ae…pq não tenta só:

SuaSessao.createCriteria(Municipio.class, "municipio")
.createAlias("municipio.estado", "estado")
.add(Restrictions.eq("estado.id", idEstado))
.list();

[/quote]
Porque ele está usando Criteria do JPA, e não do Hibernate.

Cristian, você já chegou a ver o EasyCriteria? É uma API opensource do Hébert Coelho aqui do GUJ.

Ele abstrai toda essa complexidade da API de criteria do JPA, e funciona pra diversas implementações.

Vou dar uma olhada sim, eu ja estava bem acostumado com a criteria do hibernate agora que estou a usar somente jpa estou bem perdido, vou dar um olhada nessa api valeu…

[quote=Rodrigo Sasaki][quote=XOOM]Eita que rolo isso ae…pq não tenta só:

SuaSessao.createCriteria(Municipio.class, "municipio")
.createAlias("municipio.estado", "estado")
.add(Restrictions.eq("estado.id", idEstado))
.list();

[/quote]
Porque ele está usando Criteria do JPA, e não do Hibernate.

Cristian, você já chegou a ver o EasyCriteria? É uma API opensource do Hébert Coelho aqui do GUJ.

Ele abstrai toda essa complexidade da API de criteria do JPA, e funciona pra diversas implementações.[/quote]

Hehehe…custava nada perguntar, vai que ele estava usando por masoquismo. :stuck_out_tongue:

É API do Hébert já dei uma olhada parece ser interessante, mas nunca precisei utiliza-la…da uma olhada ae Cristian, quem sabe resolve…

Utilizei a EasyCriteria mas continuo acontecendo o mesmo problema ele naum consegue pegar o idEstado que esta dentro do estado que é uma propriedade do meu bean para usar no where veja como ficou meu codigo…

EasyCriteria criteria = EasyCriteriaFactory.createQueryCriteria(this.entityManager, Municipio.class);
        criteria = criteria.whereEquals("estado.idEstado", idEstado);
        return criteria.getResultList(); 

É hehehe, já vi muita gente que conhece o criteria do Hibernate quase cair pra trás quando viu o do JPA hehehe (inclusive eu).

Mapeando a classe municipio da seguinte forma e colocando o idEstado no where funcionou beleza,mas como estava antes não tem como fazer funcionar…

@Entity
@Table(name = "municipio")
@XmlRootElement
public class Municipio implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_municipio", nullable = false)
    private Integer idMunicipio;

    @Column(name = "municipio", nullable = false, length = 100)
    private String municipio;
    
    @Column(name = "cd_legal", nullable = false, length = 45)
    private String cdLegal;

    @JoinColumn(name = "id_estado", referencedColumnName = "id_estado", insertable=false, updatable=false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Estado estado;
    
    @Column(name = "id_estado", nullable=false)
    private Integer idEstado;

Realmente a criteria do jpa é de matar.
A única coisa que presta lá eu acho que é o metamodelo.

Eu também estou apanhando com ele, mais para aprender mesmo.

Concordo com voce lele_vader é a unica coisa boa que eu vi ate agora na criteria do jpa, mas se bem que com a EasyCriteria do Uibert o negocio ficou bem mais facil…

O pior da criteria eu acho é a quantidade de classes que se tem que usar para fazer uma criteria boba.

è CriteriaBuilder,CriteriaQuery,Join,Predicate,

Isso mesmo muito trabalho para pouca coisa…

Quem é que estava nessa especificação ?
Ela é muito verbosa também.
Por conta de ser fortemente tipada, tem que chegar a fazer coisas como isso .campo