JPQL enum literals [RESOLVIDO]

Alguém poderia me ajudar?
TO com dificuldades em JPQL…

To precisando fazer uma query filtrando por um enum, to usando o nome completo do enum, e ele não tá considerando o literal como válido…

query:

SELECT DISTINCT c FROM CirculacaoDocumento c, IN (c.itemCirculacaoDocumentoCollection) AS itemCirculacaoDocumento WHERE itemCirculacaoDocumento.status = protosys.entity.enums.StatusItemCirculacaoDocumentoEnum.PENDENTE

Mensagem de erro:

line 1, column 210: invalid enum literal, the enum type protosys.entity.enums.StatusItemCirculacaoDocumentoEnum does not have an enum literal PENDENTE.

Enum:

package protosys.entity.enums;

/**
 *
 * @author root
 */
public enum StatusItemCirculacaoDocumentoEnum {
    RECEBIDO,
    ENTREGUE,
    PENDENTE,
    EXTRAVIADO;

    @Override
    public String toString() {
        switch (this){
            case RECEBIDO:
                return "Recebido";
            case ENTREGUE:
                return "Entregue";
            case PENDENTE:
                return "Pendente";
            case EXTRAVIADO:
                return "Extraviado";
            default:
                return "Selecione";
        }
    }
}

Se alguém tiver uma resposta para isso, obrigado :smiley:

Hum… parece que o enum não está mapeado, sendo assim acredito que ele vá pegar o String “pendente”…

Assim acredito que funcionaria

itemCirculacaoDocumento.status = :variavel

query.setParameter(variavel, StatusItemCirculacaoDocumentoEnum.PENDENTE)

O itemCirculacaoDocumento.status é um objeto, integer ou String?

O enum tá mapeado corretamente, tanto é que ele está sendo persistido da forma que se espera.

Quem passa os parametros para a query é o netbeans, eu não sei se eu posso enchertar um parâmetro e passar o valor dele assim, programaticamente :stuck_out_tongue:

E sim, itemCirculacaoDocumento.status é um objeto (enum). :stuck_out_tongue:

Esse é o mapeamento do campo


/**
 *
 * @author Leandro
 */
@Entity
@Table(name = "item_circulacao_documento")
@NamedQueries({
    @NamedQuery(name = "ItemCirculacaoDocumento.findAll", query = "SELECT i FROM ItemCirculacaoDocumento i"),
    @NamedQuery(name = "ItemCirculacaoDocumento.findById", query = "SELECT i FROM ItemCirculacaoDocumento i WHERE i.id = :id"),
    @NamedQuery(name = "ItemCirculacaoDocumento.findByObservacao", query = "SELECT i FROM ItemCirculacaoDocumento i WHERE i.observacao = :observacao")})
public class ItemCirculacaoDocumento implements Serializable {
    @Transient
    private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator( name = "item_circulacao_documento_id", sequenceName = "item_circulacao_documento_seq", allocationSize = 1 )
    @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "item_circulacao_documento_id" )
    @Column(name = "id")
    private Integer id;

    @Column(name = "observacao")
    private String observacao;

    @JoinColumn(name = "idCirculacaoDocumento", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private CirculacaoDocumento circulacaoDocumento;

    @JoinColumn(name = "idDocumento", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Documento documento;

    @JoinColumn(name = "idCondominio", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Condominio condominio;

    @Enumerated(EnumType.STRING)    
    private StatusItemCirculacaoDocumentoEnum status = StatusItemCirculacaoDocumentoEnum.PENDENTE;
    ...
}

E para clarear um pouco mais, essa é a exceção lançada:

Caused by: Exception [TOPLINK-8015] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.EJBQLException
Exception Description: Error compiling the query [SELECT DISTINCT c FROM CirculacaoDocumento c, IN (c.itemCirculacaoDocumentoCollection) AS itemCirculacaoDocumento WHERE itemCirculacaoDocumento.status = protosys.entity.enums.StatusItemCirculacaoDocumentoEnum.PENDENTE], line 1, column 210: invalid enum literal, the enum type protosys.entity.enums.StatusItemCirculacaoDocumentoEnum does not have an enum literal PENDENTE.
        at oracle.toplink.essentials.exceptions.EJBQLException.invalidEnumLiteral(EJBQLException.java:277)
        at oracle.toplink.essentials.internal.parsing.DotNode.validate(DotNode.java:114)
        at oracle.toplink.essentials.internal.parsing.Node.validate(Node.java:118)
        at oracle.toplink.essentials.internal.parsing.BinaryOperatorNode.validate(BinaryOperatorNode.java:58)
        at oracle.toplink.essentials.internal.parsing.EqualsNode.validate(EqualsNode.java:65)
        at oracle.toplink.essentials.internal.parsing.WhereNode.validate(WhereNode.java:58)
        at oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:235)
        at oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:211)
        at oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:201)
        at oracle.toplink.essentials.internal.parsing.EJBQLParseTree.populateReadQueryInternal(EJBQLParseTree.java:134)
        at oracle.toplink.essentials.internal.parsing.EJBQLParseTree.populateQuery(EJBQLParseTree.java:108)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:219)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:189)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:153)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.<init>(EJBQueryImpl.java:114)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.<init>(EJBQueryImpl.java:99)
        at oracle.toplink.essentials.internal.ejb.cmp3.EJBQueryImpl.<init>(EJBQueryImpl.java:86)
        at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.createQuery(EntityManagerImpl.java:204)
        ... 38 more

Como está o mapeamento?

Qual é o enum Type que vc definiu?

[quote=lelodois]Como está o mapeamento?
Qual é o enum Type que vc definiu?[/quote]

Olha um exemplo.

Referência

	@Enumerated(EnumType.ORDINAL)
	@Column(name="tipoCategoria")
	private TipoCategoria tipoCategoria;

Hibernate cfg

	<typedef class="br.com.livro.javapersistence.commons.persistence.StringEnumUserType" name="messageTypeEnum">
		<param name="enumClassname">br.com.livro.javapersistence.relacionamentos.model.TipoCategoria</param>
	</typedef>

Merge

	Categoria usuarios = (Categoria) session.merge(new Categoria("Usuários venda", TipoCategoria.LOJA));

Query

	@SuppressWarnings("unchecked")
	private void imprimirLojeirosNoConsole() {
		String hql = "From Categoria c where c.tipoCategoria = br.com.livro.javapersistence.relacionamentos.model.TipoCategoria.LOJA";
		Query query = session.createQuery(hql);
		List<Categoria> lojeiros = query.list();
		for (Categoria categoria : lojeiros) {
			System.out.println("lojeiro: " + categoria.getName());
		}
	}

E funciona normalmente…
Acabei de fazer :wink:

Só que um porém, não estou usando JPA, nem toplink, estou usando o provider hibernate diretamente.

[quote=lelodois]Como está o mapeamento?

Qual é o enum Type que vc definiu?[/quote]

Olha isso ai embaixo :stuck_out_tongue:

@Enumerated(EnumType.STRING)    
    private StatusItemCirculacaoDocumentoEnum status = StatusItemCirculacaoDocumentoEnum.PENDENTE;

Isso é requisito do meu cliente, que acha que entende alguma coisa de modelagem de banco :slight_smile: ele quer enchergar os dados no banco de forma inteligível, prefere um “PENDENTE” a um “0” lá na linha da tabela :slight_smile:

É isso… .EU podeia usar hibernate, mas eu já to usando o toplink… Nâo queria ter que alterar pra fazer funcionar, entende?

[quote=sfohart][quote=lelodois]Como está o mapeamento?

Qual é o enum Type que vc definiu?[/quote]

Olha isso ai embaixo :stuck_out_tongue:

@Enumerated(EnumType.STRING)    
    private StatusItemCirculacaoDocumentoEnum status = StatusItemCirculacaoDocumentoEnum.PENDENTE;

Isso é requisito do meu cliente, que acha que entende alguma coisa de modelagem de banco :slight_smile: ele quer enchergar os dados no banco de forma inteligível, prefere um “PENDENTE” a um “0” lá na linha da tabela :slight_smile:

É isso… .EU podeia usar hibernate, mas eu já to usando o toplink… Nâo queria ter que alterar pra fazer funcionar, entende?[/quote]

Você está usando o StringEnumUserType?

Caso contrário baixe o fonte e configure ele no seu mapeamento (olha o meu lá em cima)
http://code.google.com/p/data-access/source/browse/trunk/hibernate/src/main/java/it/filosganga/orm/hibernate/StringEnumUserType.java?spec=svn27&r=27

Abraços
fui

Gente… Eu não to usando hibernate…

Ninguém usa TopLink aqui não? :frowning:

UPDATE: Eu já alterei o mapeamento de EnumType.STRING para EnumType.ORDINAL, e continuou tudo na mesma.

Acabei tendo que fazer um negócio meio questionável aqui :stuck_out_tongue:

Consegui setar este parâmetro pelo netbeans, clicando na query (pelo editor visual) e colocando esse código naquela parte de pós criação do componente.

A minha query acabou ficando assim:

SELECT DISTINCT c FROM CirculacaoDocumento c, IN (c.itemCirculacaoDocumentoCollection) AS itemCirculacaoDocumento WHERE itemCirculacaoDocumento.status = :statusItemCirculacaoDocumento

Obrigado, pessoal :slight_smile:

Seria interessante vc procurar alguma coisa similar ao StringUserType do hibernate para o topLink…

Coloca o post como resolvido :wink: