Solucionado (ver solução)
Solucionado
(ver solução)
11
respostas

Erro ao @Temporal(TemporalType.TIME)

estou recebendo o seguinte erro ao tentar armazenar apenas a hora:

Calendar cannot persist TIME only

Tentei armazenar TIMESTAMP, funcionou, com DATE, também, mas com a hora esta dando esse erro :/

e quando ou por @ManyToMay, estou recebendo esse erro:

OBS: Estou usando MySQL e o Postgres

Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements

Meus códigos segue abaixo.

CLASSE FUNCIONARIO

@Entity
public class Funcionario {

    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer id;

    private String nome;

    @Temporal(TemporalType.DATE)
    private Calendar data_nasc;

    private String email;

    //Gettrs e setters....
CLASSE ORDEM DE SERVIÇO

@Entity
public class OrdemDeServico {

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @ManyToOne
    private UsuarioComun nome_criador;

    @ManyToMany
    private Funcionario nome_realizou;

    @ManyToMany
    private Servico ordem_servico;

    @Enumerated(EnumType.STRING)
    private tipoStatus status;

    @Temporal(TemporalType.TIME)
    private Calendar tempo_total_atendimento;

    //Getters and Setters
CLASSE SERVIÇO

@Entity
public class Servico {
    // Identity para MYSQL AUTO para postgres
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @Enumerated(EnumType.STRING)
    private tipoServico nome_servico;

    private String descricao;

    @Temporal(TemporalType.TIME)
    private Calendar tempo_resposta;

    @Temporal(TemporalType.TIME)
    private Calendar tempo_servico;

    //Gettrs e setters
CLASSE PRINCIPAL

public class MinhaClassePrincipal {
    public static void main(String[] args) {

        UsuarioComun user = new UsuarioComun();
        user.setNome("Ismael");
        user.setEmail("Not null");
        user.setData_nasc(Calendar.getInstance());

        Funcionario func = new Funcionario();
        func.setNome("Ismael");
        func.setEmail("Not null");
        func.setData_nasc(Calendar.getInstance());

        Servico ser = new Servico();
        ser.setNome_servico(tipoServico.FORMATAÇÃO_DE_COMPUTADOR);
        ser.setDescricao("Estamos formatando o computador");
        ser.setTempo_resposta(Calendar.getInstance());
        ser.setTempo_servico(Calendar.getInstance());

        OrdemDeServico servico = new OrdemDeServico();
        servico.setNome_criador(user);
        servico.setNome_realizou(func);
        servico.setOrdem_servico(ser);
        servico.setStatus(tipoStatus.PENDENTE);
        servico.setTempo_total_atendimento(Calendar.getInstance());

        EntityManager manager = new UTIL().getEntity();
        manager.getTransaction().begin();

        manager.persist(user);
        manager.persist(func);
        manager.persist(ser);
        manager.persist(servico);

        manager.getTransaction().commit();
        manager.close();
    }
}
11 respostas

Oi Ismael,

Testou passando Calendar.getInstance().getTime() ?

Em relação ao erro em utilizar uma dessas anotações

Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements

Quer dizer que você esta tentando mapear um objeto e não uma coleção dele.

Utilize uma List dos objetos que precisar mapear com essas anotações.

@ManyToMany
private List<Funcionario> funcionariosQueRealizaram;

@ManyToMany
private List<Servico> ordensDeServico;

Vou tentar ao chegar em casa, apesar de já está claro na mensagem (non collection) não sabia que deveria ser passado uma lista.

Se tudo der certo, marco como resolvido. Obrigado

Ismael, List é uma das sub interfaces de Collection, não tenho certeza, mas acredito que utilizam collection na msg da exception, para generalizar e não limitar em apenas um tipo de Collection, tem mais informações sobre outras interfaces na documentação.

https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html

Então pode ser que necessáriamente não precise ser um List, depende do que você precisa, eu indiquei a List por ser a mais comum nessa situação.

Entendi, conheço a classe Collection, fiz a alteração que você sugeriu, porém não estou sabendo como adicionar valores a eles.

No caso, nessa parte, esta gerando um erro, pois estou tentado passar um objeto e não uma lista como esperado:

 servico.setNome_realizou(func);
 servico.setOrdem_servico(ser);

Certo, SetName ... Espera uma lista, fiquei meio perdido em como vou adicionar valores a esses dois metodos. :/

solução!

Ismael, crie um método para cada uma das List, recebendo um objeto do tipo dessa lista, que adicione dentro dessa lista.

Por exemplo:

public void adicionaRealizou(Funcionario funcionario) {
   this.funcionariosQueRealizaram.add(funcionario);
}

Mas naturalmente, antes disso você vai precisar desse objeto criado, assim você atribui o nome a esse objeto, antes de passar ele para o método adiciona.

Funcionario funcionario = new Funcionario();
funcionario.setNome("nome");

OrdemDeServico ordem = new OrdemDeServico();
ordem.adicionaRealizou(funcionario);

A lógica pode ser mais ou menos isso.

ainda continua gerando erro na hora de passar,

Funcionario funcionario = new Funcionario();
funcionario.setNome("nome");

Obrigado pela ajuda, vou deixar @ManyToOne mesmo :/ Com o tempo vejo meios de como usar ManyToMany.

Obrigado por tudo. Finalizando o tópico.

Ismael, não fui completamente claro, você inicializou a List?

@ManyToMany
private List<Funcionario> funcionariosQueRealizaram = new ArrayList<>();

sim, nessa parte, pedi pra fazer cast: no caso fica a mesma do mesmo jeito que antes.

public void adicionaRealizou(Funcionario funcionario) {
   this.funcionariosQueRealizaram.add( (Funcionaio) funcionario);
}

Não deve ser necessário esse cast.

O mesmo erro do @ManyToMany? Veja que para um Many você precisa de um grupo de objetos, nesse caso utilizamos uma List, mas você utilizou em apenas um lado.

Se na classe OrdemDeServicos você tem

@ManyToMany
private List<Funcionario> funcionariosQueRealizaram = new ArrayList<>();

Na classe Funcionario, você vai precisar de uma outra List, de OrdemDeServicos

@ManyToMany
private List<OrdemDeServicos> ordensDeServico = new ArrayList<>();

Mas entenda que estou seguindo a logica do que você precisa, se essa lógica é a correta para o funcionamento da aplicação, eu não sei dizer.

Após isso você pode utilizar a anotação @JoinTable em uma das duas listas, em cima ou embaixo do @ManyToMany, definindo o name, a joinColum e a inverseJoinColums, para informar ao JPA, qual das duas será a dona do relacionamento e qual não será.

Exemplo: Aqui a dona é claramente o funcionario, você então altera para a lógica que você precisa.

@JoinTable(name = "funcionario_ordem", joinColumns = @JoinColumn(name = "funcionario_id"), inverseJoinColumns = @JoinColumn(name = "ordem_id"))

Oi Ismael, tudo bem?

Sobre armazenar apenas a hora, segundo a documentação deveria funciona com Calendar também:

Type used to indicate a specific mapping of java.util.Date or java.util.Calendar.

Mas aparentemente o hibernate não implementa o @TemporalType.TIME pro Calendar, por isso o erro. Eu não testei com outras implementações, ex: EclipseLink.

Eu tenho que dar uma olhada melhor nisso.

Mas se você utilizar Date e marcar para armazenar apenas a hora pelo que testei aqui funciona ok! :)

Abraço.

Obrigado pessoal, funcionou tranquilo aqui, fiz umas alterações XD

Obrigado