Bom galera, preciso fazer uma consulta que mostre pessoas que ainda não tem plano de saúde associado. No meu modelo tenho a classe pessoa e a classe plano de saúde onde pessoa tem um list de plano de saúde. Como faço uma consulta em JPQL que mostre todas as pessoas que não tem plano de saúde ??
Basta você ver quais pessoas tem o plano de saúde null.
Esse post aqui pode te ajudar: JPA Consultas e Dicas.
Não é tão simples assim, esta opção só funciona se o relacionamento for do tipo one to one, o plano de saúde é do tipo List, quando tento esta opção apresenta erro na consulta.
[quote=leopose]Não é tão simples assim, esta opção só funciona se o relacionamento for do tipo one to one, o plano de saúde é do tipo List, quando tento esta opção apresenta erro na consulta.[/quote]Como você tentou?
Como está seu código de consulta (coloca a JPQL apenas) e como está o mapeamento?
Vou dificultar um pouquinho, o exemplo que citei era pra facilitar a abstração da minha dúvida. Na verdade meu modelo é o seguinte. Tenho a classe Integrante que tem uma lista da classe ProjetoExtensão.
Ficando desta forma na classe Integrante:
@OneToMany
private List<ProjetoExtensao> projeto;
No link que vc me passou verifiquei que para fazer o filtro que to querendo preciso usar o IS EMPTY, pois o null só funciona para one to one como tinha falado.
Beleza, ficou desta forma:
String sql = "Select i from Integrante i where i.projeto IS EMPTY";
Query query = em.createQuery(sql);
return query.getResultList();
Mas meu problema é um pouco maior, preciso incluir um filtro ai. Quero saber quais integrantes não estão associados a um projeto especifico. Fiz uma sql para isso e ficou da seguinte forma :
Quero saber como faço essa consulta usando JPQL. Podem me ajudar?
“s.projeto_id is null” para que isso? pq não s.projeto is null
Se você tem uma lista, não tem como você acessar o id desse modo.
Eu não entendi oq seria o projeto extensão. A quem ele está ligado?
s.projeto_id is null foi usando NativeQuery. Fiz desta forma sem usar JPQL, usei SQL mesmo, direto no banco. Projeto extensão é o nome da Classe e está ligado a Integrante como no exemplo que coloquei.
Segue o modelo da classe Integrante:
@OneToMany
private List<ProjetoExtensao> projeto;
Alguém ???
Ok, vou testar essa solução quando chegar em casa e posto aqui a resposta. Valeuuu. Seu blog ajudou muito com outras dúvidas também. rsrs
Nada feito ainda amigo. Tentei usando o NOT IN como sugeriu mas não funcionou.
Segue o codigo:
public List getIntegrantesSemProjeto(Long filtroprojeto) {
String sql = "Select i from Integrante i where i.projeto not in (Select p From ProjetoExtensao p Where p.id="+filtroprojeto+")";
Query query = em.createQuery(sql);
return query.getResultList();
}
O resultado do erro:
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: Erro de sintaxe: Encountered "IN" at line 1, column 108.
Error Code: -1
Call: SELECT DISTINCT t1.DTYPE FROM PROJETOEXTENSAO t0, INTEGRANTE_PROJETOEXTENSAO t2, INTEGRANTE t1 WHERE ( NOT IN (SELECT t3.ID, t3.DATAINICIO, t3.DESCRICAO, t3.NOMEPOJETO, t3.RESPONSAVEL_ID FROM PROJETOEXTENSAO t3 WHERE (t3.ID = ?)) AND ((t2.Integrante_ID = t1.ID) AND (t0.ID = t2.projeto_ID)))
bind => [1 parameter bound]
Query: ReadAllQuery(referenceClass=Integrante sql="SELECT DISTINCT t1.DTYPE FROM PROJETOEXTENSAO t0, INTEGRANTE_PROJETOEXTENSAO t2, INTEGRANTE t1 WHERE ( NOT IN (SELECT t3.ID, t3.DATAINICIO, t3.DESCRICAO, t3.NOMEPOJETO, t3.RESPONSAVEL_ID FROM PROJETOEXTENSAO t3 WHERE (t3.ID = ?)) AND ((t2.Integrante_ID = t1.ID) AND (t0.ID = t2.projeto_ID)))")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:644)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1702)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:566)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:264)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:646)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2592)
at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingDefaultMultipleTableSubclassRead(InheritancePolicy.java:1318)
at org.eclipse.persistence.descriptors.InheritancePolicy.selectAllRowUsingMultipleTableSubclassRead(InheritancePolicy.java:1422)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2548)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:418)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1097)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:829)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1056)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:390)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1144)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2863)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1501)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1483)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1457)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:485)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
at Controle.IntegranteFacade.getIntegrantesSemProjeto(IntegranteFacade.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
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:5366)
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 com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
at sun.reflect.GeneratedMethodAccessor94.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
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:5338)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5326)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
... 68 more
Caused by: java.sql.SQLSyntaxErrorException: Erro de sintaxe: Encountered "IN" at line 1, column 108.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.Connection.prepareStatement(Unknown Source)
at com.sun.gjc.spi.base.ConnectionHolder.prepareStatement(ConnectionHolder.java:502)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.prepareStatement(DatabaseAccessor.java:1474)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.prepareStatement(DatabaseAccessor.java:1423)
at org.eclipse.persistence.internal.databaseaccess.DatabaseCall.prepareStatement(DatabaseCall.java:697)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:585)
... 113 more
Caused by: org.apache.derby.client.am.SqlException: Erro de sintaxe: Encountered "IN" at line 1, column 108.
at org.apache.derby.client.am.Statement.completeSqlca(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parsePrepareError(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.parsePRPSQLSTTreply(Unknown Source)
at org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(Unknown Source)
at org.apache.derby.client.am.Statement.readPrepareDescribeOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.readPrepareDescribeInputOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.flowPrepareDescribeInputOutput(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.prepare(Unknown Source)
at org.apache.derby.client.am.Connection.prepareStatementX(Unknown Source)
... 119 more
É apenas erro de sintaxe. Tente
edit: Fiz usando a Query do hibernate. Deve funcionar ai. Não sei se o os nomes dos seus atributos está assim, mas a ideia é a mesma.
Farei o teste mais tarde, mais uma duvida. Pela sintaxe estou dizendo que Integrante não está em Projeto de Extensão. É isso ? Não faz muito sentido…
Ele faz um select na tabela ProjetoExtensao de acordo com o parametro(tabela A). Depois faz um select na tabela integrante(tabela B), compara com a tabela A e e monta uma tabela apenas com os integrantes que não estão na Tabela A.
Só usei NOT IN no SQL e pelo que vi, no JPA é um pouco diferente. Não tenho uma base de dados aqui para testar.
Verifiquei aqui, na Classe ProjetoExtensao não tenho esse atributo de integrantes.
Você tem uma tabela onde tem o id do integrante e o id do projeto, certo? O select que está entre parenteses deve ser nessa tabela.
algo como "FROM Integrante i WHERE i.id NOT IN (SELECT t.id_integrante FROM tabela_com_projeto_e_integrante t WHERE t.id="+filtroprojeto+")";