Erro ao salvar lista de objetos em JSF

Pessoal, não estou conseguindo salvar esta lista de obj templates no banco, para que eu possa depois apresentar em outra tela recebo o erro:

create table HT_Compra (codCompra integer not null, hib_sess_id CHAR(36))
Informações: HHH000228: Running hbm2ddl schema update
Informações: HHH000102: Fetching database metadata
Informações: HHH000396: Updating schema
Informações: HHH000261: Table found: CLIENTE
Informações: HHH000037: Columns: [codcliente, senha, telefone, endereco, cpf, celular, nome, nomeacesso, email]
Informações: HHH000108: Foreign keys: []
Informações: HHH000126: Indexes: [rdb$primary1]
Informações: HHH000261: Table found: COMPRA
Informações: HHH000037: Columns: [codcompra, codcliente, valortotal]
Informações: HHH000108: Foreign keys: [fk_lmvkq9po29bbw6p5wnbdbgsp6]
Informações: HHH000126: Indexes: [rdb$primary2, fk_lmvkq9po29bbw6p5wnbdbgsp6]
Informações: HHH000261: Table found: COMPRA_TEMPLATE
Informações: HHH000037: Columns: [listacompra_codtemplate, compra_codcompra]
Informações: HHH000108: Foreign keys: [fk_je0bj9mb6pnyiv78nlt3ev8rx, fk_diuh7o1goigr5oo1ta2uqdjx7]
Informações: HHH000126: Indexes: [fk_je0bj9mb6pnyiv78nlt3ev8rx, fk_diuh7o1goigr5oo1ta2uqdjx7, uk_diuh7o1goigr5oo1ta2uqdjx7]
Informações: HHH000261: Table found: TEMPLATE
Informações: HHH000037: Columns: [categoria, valor, nome, codtemplate]
Informações: HHH000108: Foreign keys: []
Informações: HHH000126: Indexes: [rdb$primary3]
Informações: HHH000232: Schema update complete
WARN: HHH000436: Entity manager factory name (template_persistenciaPU) is already registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name’
Informações: Hibernate:
select
template0_.codTemplate as codTempl1_3_,
template0_.categoria as categori2_3_,
template0_.nome as nome3_3_,
template0_.valor as valor4_3_
from
Template template0_


  package Modelo;

    import java.io.Serializable;
    import java.util.Objects;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.SequenceGenerator;
    import javax.persistence.Table;

    @Entity
    @Table(name = "Cliente")
    @SequenceGenerator(name = "Gerador_codCliente", initialValue = 1, allocationSize = 1, sequenceName = "Gerador_codCliente")
    public class Cliente implements Serializable {

        private static final long serialVersionUID = -4846590792485118024L;

        @Id
        @GeneratedValue(generator = "Gerador_codCliente", strategy = GenerationType.SEQUENCE)
        private Long codCliente;

        @Column(name = "nome", length = 100, nullable = false)
        private String nome;

        @Column(name = "cpf", length = 100, nullable = false)
        private int cpf;

        @Column(name = "email", length = 100, nullable = false)
        private String email;

        @Column(name = "senha", length = 100, nullable = false)
        private String senha;

        @Column(name = "telefone", length = 100, nullable = false)
        private int telefone;

        @Column(name = "celular", length = 100, nullable = false)
        private int celular;

        @Column(name = "nomeAcesso", length = 100, nullable = false)
        private String nomeAcesso;

        @Column(name = "endereco", length = 100, nullable = false)
        private String endereco;

        public Long getCodCliente() {
            return codCliente;
        }

        public void setCodCliente(Long codCliente) {
            this.codCliente = codCliente;
        }

        public String getNome() {
            return nome;
        }

        public void setNome(String nome) {
            this.nome = nome;
        }

        public int getCpf() {
            return cpf;
        }

        public void setCpf(int cpf) {
            this.cpf = cpf;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getSenha() {
            return senha;
        }

        public void setSenha(String senha) {
            this.senha = senha;
        }

        public int getTelefone() {
            return telefone;
        }

        public void setTelefone(int telefone) {
            this.telefone = telefone;
        }

        public int getCelular() {
            return celular;
        }

        public void setCelular(int celular) {
            this.celular = celular;
        }

        public String getNomeAcesso() {
            return nomeAcesso;
        }

        public void setNomeAcesso(String nomeAcesso) {
            this.nomeAcesso = nomeAcesso;
        }

        public String getEndereco() {
            return endereco;
        }

        public void setEndereco(String endereco) {
            this.endereco = endereco;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 83 * hash + Objects.hashCode(this.codCliente);
            hash = 83 * hash + Objects.hashCode(this.nome);
            hash = 83 * hash + this.cpf;
            hash = 83 * hash + Objects.hashCode(this.email);
            hash = 83 * hash + Objects.hashCode(this.senha);
            hash = 83 * hash + this.telefone;
            hash = 83 * hash + this.celular;
            hash = 83 * hash + Objects.hashCode(this.nomeAcesso);
            hash = 83 * hash + Objects.hashCode(this.endereco);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Cliente other = (Cliente) obj;
            if (this.cpf != other.cpf) {
                return false;
            }
            if (this.telefone != other.telefone) {
                return false;
            }
            if (this.celular != other.celular) {
                return false;
            }
            if (!Objects.equals(this.nome, other.nome)) {
                return false;
            }
            if (!Objects.equals(this.email, other.email)) {
                return false;
            }
            if (!Objects.equals(this.senha, other.senha)) {
                return false;
            }
            if (!Objects.equals(this.nomeAcesso, other.nomeAcesso)) {
                return false;
            }
            if (!Objects.equals(this.endereco, other.endereco)) {
                return false;
            }
            if (!Objects.equals(this.codCliente, other.codCliente)) {
                return false;
            }
            return true;
        }

    }

    package Modelo;

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    import java.util.Objects;
    import javax.persistence.Column;
    import javax.persistence.ElementCollection;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.OneToMany;
    import javax.persistence.SequenceGenerator;

    import javax.persistence.Table;

    @Entity
    @Table(name = "Compra")
    @SequenceGenerator(initialValue = 1, name = "Gerador_codCompra", sequenceName = "Gerador_codCompra", allocationSize = 1)
    public class Compra implements Serializable {

        private static final long serialVersionUID = -4846590792485118024L;
        @Id
        @GeneratedValue(generator = "Gerador_codCompra", strategy = GenerationType.SEQUENCE)
        private int codCompra;
        
        @OneToMany(targetEntity = Template.class)
        @Column(name = "Lista de Templates")
        @ElementCollection(targetClass = Template.class)
        private Collection<Template> listaCompra;

        @ManyToOne(targetEntity = Cliente.class)
        @JoinColumn(name="codCliente")
        private Cliente cliente;

        @Column(name = "ValorTotal")
        private double valorTotal;

        public int getCodCompra() {
            return codCompra;
        }

        public void setCodCompra(int codCompra) {
            this.codCompra = codCompra;
        }

        public Collection<Template> getListaCompra() {
            return listaCompra;
        }

        public void setListaCompra(Collection<Template> listaCompra) {
            this.listaCompra = listaCompra;
        }

        public Cliente getCliente() {
            return cliente;
        }

        public void setCliente(Cliente cliente) {
            this.cliente = cliente;
        }

        public double getValorTotal() {
            return valorTotal;
        }

        public void setValorTotal(double valorTotal) {
            this.valorTotal = valorTotal;
        }

        @Override
        public int hashCode() {
            int hash = 3;
            hash = 67 * hash + this.codCompra;
            hash = 67 * hash + Objects.hashCode(this.listaCompra);
            hash = 67 * hash + Objects.hashCode(this.cliente);
            hash = 67 * hash + (int) (Double.doubleToLongBits(this.valorTotal) ^ (Double.doubleToLongBits(this.valorTotal) >>> 32));
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Compra other = (Compra) obj;
            if (this.codCompra != other.codCompra) {
                return false;
            }
            if (Double.doubleToLongBits(this.valorTotal) != Double.doubleToLongBits(other.valorTotal)) {
                return false;
            }
            if (!Objects.equals(this.listaCompra, other.listaCompra)) {
                return false;
            }
            if (!Objects.equals(this.cliente, other.cliente)) {
                return false;
            }
            return true;
        }

    }


    package DAO;

    import Controle.Conexao;
    import Modelo.Compra;
    import java.util.Collection;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Query;
    import Modelo.Template;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;

    public class Compra_DAO {

        private final EntityManager con;
        private EntityTransaction tr;
      //  private Collection<Template> l;

        public Compra_DAO() {

            con = Conexao.getAcesso();
           // l = new ArrayList<Template>();
        }

        public void gravar(Compra compra)
                throws Exception {

            tr = con.getTransaction();
            tr.begin();
            con.persist(compra);
            tr.commit();
        }

        public List<Compra> todos() {

            Query consulta
                    = con.createQuery("from Compra");
            return consulta.getResultList();
        }
        
        

    }

    package DAO;

    import Controle.Conexao;
    import Modelo.Cliente;
    import java.util.Collection;

    import java.util.List;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Query;

    public class Cliente_DAO {

        private final EntityManager con;
        private EntityTransaction tr;
        private Query consulta;
        private Collection<Cliente> l;

        public Cliente_DAO() {

            con = Conexao.getAcesso();
        }

        public void gravar(Cliente cliente)
                throws Exception {

            tr = con.getTransaction();
            tr.begin();
            con.persist(cliente);
            tr.commit();
        }

        public void alterar(Cliente cliente) {
            tr = con.getTransaction();
            tr.begin();
            con.merge(cliente);
            tr.commit();
        }

        public void excluir(Cliente cliente) {
            tr = con.getTransaction();
            tr.begin();

            cliente = con.find(Cliente.class, cliente.getCodCliente());

            if (cliente != null) {
                con.remove(cliente);
            }
            tr.commit();

        }

        public List<Cliente> todos() {

            Query consulta
                    = con.createQuery("from Cliente");
            return consulta.getResultList();
        }

        public List<Cliente> login(String email, String senha) {

            consulta = con.createQuery("from Cliente cliente where cliente.email = :em and cliente.senha = :se ");

            consulta.setParameter("em", email);
            consulta.setParameter("se", senha);
            return consulta.getResultList();

        }

        //GETTERS & SETTERS
        public EntityTransaction getTr() {
            return tr;
        }

        public void setTr(EntityTransaction tr) {
            this.tr = tr;
        }

        public Query getConsulta() {
            return consulta;
        }

        public void setConsulta(Query consulta) {
            this.consulta = consulta;
        }

        public Collection<Cliente> getL() {
            return l;
        }

        public void setL(Collection<Cliente> l) {
            this.l = l;
        }

    }

    package Controle;

    import DAO.Compra_DAO;
    import Modelo.Compra;
    import DAO.Pagamento_DAO;
    import DAO.Template_DAO;
    import Modelo.Pagamento;
    import Modelo.Cliente;
    import Modelo.Template;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Objects;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.faces.application.FacesMessage;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.RequestScoped;
    import javax.faces.bean.SessionScoped;
    import javax.faces.context.FacesContext;

    @ManagedBean(name = "RegistrarCompra")
    @SessionScoped
    public class RegistrarCompraRegra {

        private Compra compra;
        private Collection<Template> homeTemplates;
        private Collection<Template> carrinhoComTemplates;
        private int templatesSelecionados = 0;
        private Template template;
        private Cliente cliente;
        private double valorTotal;

        public RegistrarCompraRegra() {
            compra = new Compra();
            template = new Template();
            cliente = new Cliente();
            homeTemplates = new ArrayList<Template>();
            carrinhoComTemplates = new ArrayList<Template>();  
            compra.setListaCompra(this.carrinhoComTemplates);
        }

        public Collection<Template> getHomeTemplates() {
            Template_DAO tDAO;
            tDAO = new Template_DAO();
            this.homeTemplates = tDAO.todos();

            return this.homeTemplates;
        }

        public void usuarioLogado() {
            Compra_DAO cDAO = new Compra_DAO();
            ClienteRegra cRegra = new ClienteRegra();
            compra.setCliente(cRegra.getCliente());
        }

        public void valorTotalSoma() {

            this.templatesSelecionados += 1;
            this.valorTotal += template.getValor();
            compra.setValorTotal(valorTotal);

        }

        public void valorTotalSubtrai() {

            this.templatesSelecionados -= 1;
            this.valorTotal -= template.getValor();
            compra.setValorTotal(valorTotal);

        }

        public String adicionaCarrinho() {
            this.valorTotalSoma();
            carrinhoComTemplates.add(template);
            return null;
        }

        public String removeCarrinho() {
            this.valorTotalSubtrai();
            carrinhoComTemplates.remove(template);
            return null;
        }
        

        public String gravarCompra() {

            Compra_DAO cDAO = new Compra_DAO();
            try { 
                compra.setListaCompra(carrinhoComTemplates);
                cDAO.gravar(compra);
            } catch (Exception ex) {
                FacesContext fc = FacesContext.getCurrentInstance();
                FacesMessage fm = new FacesMessage(ex.getMessage());
                fc.addMessage(null, fm);
                return null;
            }
            return "Carrinho";
        }

        public Compra getCompra() {
            return compra;
        }

        public void setCompra(Compra compra) {
            this.compra = compra;
        }

        public Collection<Template> getCarrinhoComTemplates() {
            return carrinhoComTemplates;
        }

        public void setCarrinhoComTemplates(Collection<Template> carrinhoComTemplates) {
            this.carrinhoComTemplates = carrinhoComTemplates;
        }

        public int getTemplatesSelecionados() {
            return templatesSelecionados;
        }

        public void setTemplatesSelecionados(int templatesSelecionados) {
            this.templatesSelecionados = templatesSelecionados;
        }

        public Template getTemplate() {
            return template;
        }

        public void setTemplate(Template template) {
            this.template = template;
        }

        public Cliente getCliente() {
            return cliente;
        }

        public void setCliente(Cliente cliente) {
            this.cliente = cliente;
        }

        public double getValorTotal() {
            return valorTotal;
        }

        public void setValorTotal(double valorTotal) {
            this.valorTotal = valorTotal;
        }

        @Override
        public int hashCode() {
            int hash = 3;
            hash = 73 * hash + Objects.hashCode(this.compra);
            hash = 73 * hash + Objects.hashCode(this.homeTemplates);
            hash = 73 * hash + Objects.hashCode(this.carrinhoComTemplates);
            hash = 73 * hash + this.templatesSelecionados;
            hash = 73 * hash + Objects.hashCode(this.template);
            hash = 73 * hash + Objects.hashCode(this.cliente);
            hash = 73 * hash + (int) (Double.doubleToLongBits(this.valorTotal) ^ (Double.doubleToLongBits(this.valorTotal) >>> 32));
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final RegistrarCompraRegra other = (RegistrarCompraRegra) obj;
            if (this.templatesSelecionados != other.templatesSelecionados) {
                return false;
            }
            if (Double.doubleToLongBits(this.valorTotal) != Double.doubleToLongBits(other.valorTotal)) {
                return false;
            }
            if (!Objects.equals(this.compra, other.compra)) {
                return false;
            }
            if (!Objects.equals(this.homeTemplates, other.homeTemplates)) {
                return false;
            }
            if (!Objects.equals(this.carrinhoComTemplates, other.carrinhoComTemplates)) {
                return false;
            }
            if (!Objects.equals(this.template, other.template)) {
                return false;
            }
            if (!Objects.equals(this.cliente, other.cliente)) {
                return false;
            }
            return true;
        }

    }

    package Controle;

    import DAO.Cliente_DAO;
    import Modelo.Cliente;
    import java.util.Collection;
    import java.util.List;
    import javax.faces.bean.ManagedBean;
    import javax.faces.application.FacesMessage;
    import javax.faces.bean.RequestScoped;
    import javax.faces.bean.SessionScoped;
    import javax.faces.context.FacesContext;

    @ManagedBean(name = "ClienteRegra")
    @SessionScoped
    public class ClienteRegra {

        private Cliente cliente;
        private Collection<Cliente> lista;
        private String email;
        private String senha;

        public ClienteRegra() {
            cliente = new Cliente();

        }

        public String editar() {

            return "cliente/editar";
        }

        public String alterar() {

            Cliente_DAO cDAO = new Cliente_DAO();

            cDAO.alterar(cliente);

            return "index";

        }

        public String gravar() {
            Cliente_DAO cDAO = new Cliente_DAO();
            if (this.cliente.getCodCliente() == null) {
                try {
                    cDAO.gravar(this.cliente);
                } catch (Exception ex) {
                    FacesContext fc = FacesContext.getCurrentInstance();
                    FacesMessage fm = new FacesMessage("NÃO SALVOU");
                    fc.addMessage(null, fm);
                    return null;
                }
            } else {
                cDAO.alterar(this.cliente);
            }

            return "index";
        }

        public String cancelar() {

            return "index";
        }

        public String excluir() {
            Cliente_DAO cDAO = new Cliente_DAO();
            cDAO.excluir(cliente);
            return "exibir_lista";
        }

        public Collection<Cliente> getLista() {
            Cliente_DAO cDAO = new Cliente_DAO();
            this.lista = cDAO.todos();
            return this.lista;
        }

        public boolean verificaUsuario() {
            Cliente_DAO cDAO = new Cliente_DAO();
            lista = cDAO.login(this.email, this.senha);
            if (lista.size() != 1) {

                return false;
            } else {
                for (Cliente c : lista) {
                    this.cliente = c;
                }

                return true;

            }
        }

        public String efeturarLogin() {
            if (this.verificaUsuario() == true) {
                return "index";
            } else {

                FacesContext fc = FacesContext.getCurrentInstance();
                FacesMessage fm = new FacesMessage("Campos inválidos");
                fc.addMessage(null, fm);

                return null;
            }

        }

        public Cliente getCliente() {
            return cliente;
        }

        public void setCliente(Cliente cliente) {
            this.cliente = cliente;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getSenha() {
            return senha;
        }

        public void setSenha(String senha) {
            this.senha = senha;
        }

    }