实体管理器中的合并不起作用

时间:2014-09-22 15:14:53

标签: java hibernate jpa

大家好我使用hibernate来管理我的数据库事务,find和createquery方法运行良好,但是当我进行合并时没有任何反应,并且没有显示任何错误。

我正在尝试从一个Repositorio中删除一些分类。 我在属性

中正确更改了所有值
private List<ICategoria> categoriaList;

但是在合并中我遇到了问题

这是我的实体Repositorio,Repositorio有很多类别。

@Entity
public class Repositorio extends EntityBean implements IRepositorio {

private static final long serialVersionUID = 1L;

private String nome;

@OneToMany(targetEntity=Categoria.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="repositorio")
@Fetch(FetchMode.SELECT)
private List<ICategoria> categoriaList;

public String getNome() {
    return nome;
}
public void setNome(String nome) {
    this.nome = nome;
}
public void incluirCategoria(ICategoria categoria) {

}
public void excluirCategoria(ICategoria categoria) {

}   
public List<ICategoria> getCategoriaList() {
    if (categoriaList == null) {
        categoriaList = new ArrayList<ICategoria>();
    }

    return categoriaList;
}
@Override
public String toString() {
    return this.nome;
}

}

这是我的实体Categoria

@Entity
public class Categoria extends EntityBean implements ICategoria {
private static final long serialVersionUID = 1L;

@OneToMany(targetEntity=Documento.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="categoria")
private List<IDocumento> documentoList;

@ManyToOne(targetEntity=Repositorio.class)
private IRepositorio repositorio;
private String nome;

@ManyToOne(targetEntity=Categoria.class)
private ICategoria categoria;//pai

@OneToMany(targetEntity=Categoria.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="categoria")
private List<ICategoria> categoriaList;

public IRepositorio getRepositorio() {
    return repositorio;
}
public String getNome() {
    return nome;
}
public void setNome(String nome) {
    this.nome = nome;
}
public ICategoria getCategoria() {
    return categoria;
}
public List<ICategoria> getCategoriaList() {
    if (categoriaList == null) {
        categoriaList = new ArrayList<ICategoria>();
    }

    return categoriaList;
}
@Override
public String toString(){
    return this.nome;
}

public List<IDocumento> getDocumentoList() {

    return documentoList;
}
public void setCategoria(ICategoria categoria) {
    this.categoria = categoria;     
}
public void setCategoriaList(List<ICategoria> categoriaList) {
    this.categoriaList = categoriaList;
}
@Override
public void setRepositorio(IRepositorio repositorio) {
    this.repositorio = repositorio;     
}
}

这是我的更新方法

public T update(T entity) {

    beginTransaction();
    T mergedEntity = entityManager.merge(entity); 
    entityManager.flush();
    commit();
    return mergedEntity;
}

更新

这里我调用DAO来获取我的元素方法excluirCategoria是我删除类别过程的地方

public class RepositorioFacade implements IRepositorioFacade {

    private IRepositorioDAO repositorioDAO;

    public List<IRepositorio> listar() {
        return getRepositorioDAO().list();
    }

    public IRepositorio criar() {
        return EntityBeanFactory.getRepositorio();      
    }

    public void excluir(IRepositorio repositorio) {
        getRepositorioDAO().delete(repositorio);        
    }

    public void gravar(IRepositorio repositorio) {
        getRepositorioDAO().save(repositorio);
    }       

    public void incluirCategoria(IRepositorio repositorio, ICategoria categoria) {      
        categoria.setRepositorio(repositorio);
        repositorio.getCategoriaList().add(categoria);      
    }

    public void excluirCategoria(IRepositorio repositorio, ICategoria categoria) {      
        while (categoria.getCategoriaList().size() > 0) {
            excluirCategoria(repositorio, categoria.getCategoriaList().get(0));
        }

        if (categoria.getCategoria() != null) {
            ICategoria catPai = categoria.getCategoria();

            if (catPai.getCategoriaList().indexOf(categoria) >= 0)
                catPai.getCategoriaList().remove(categoria);
        }

        if (repositorio.getCategoriaList().indexOf(categoria) >= 0) {
            repositorio.getCategoriaList().remove(categoria);   
        }
    }

    private IRepositorioDAO getRepositorioDAO(){
        if (repositorioDAO == null){
            repositorioDAO = DAOFactory.getRepositorioDAO();
        }

        return repositorioDAO;
    }


    @Override
    public void incluirSubCategoria(ICategoria categoriaPai, ICategoria categoriaFilho) {//(categoria selecionada e categoria nova (do pooup))
        categoriaFilho.setCategoria(categoriaPai);// 
        categoriaPai.getCategoriaList().add(categoriaFilho); //esto es para que el papa quede acctualizado pero para hibernate no se precisa
    }
    public IRepositorio find(int id){

        return DAOFactory.getRepositorioDAO().find(id);


    }
}

这是我的DAO,list方法的事务方法是元素存储库。

public class GenericDAO<T extends IEntityBean> {

    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("WSysGED");
    protected EntityManager entityManager = emf.createEntityManager();
    protected Class<?> entityClass;

    private void beginTransaction() {
        entityManager.getTransaction().begin();     
    }

    private void commit() {
        entityManager.getTransaction().commit();
    }


    public GenericDAO(Class<?> entityClass) {
        this.entityClass = entityClass;
    }

    public void save(T entity) {                                
        if (entity.getId() == 0) {
            beginTransaction();
            entityManager.persist(entity);
            commit();
        } else {
            update(entity);
        }               
    }

    public void delete(T entity) {
        beginTransaction();
        entityManager.remove(entity);
        commit();       
    }

    public T update(T entity) {
        System.out.println("update");       
        beginTransaction();
        T mergedEntity = entityManager.merge(entity); 
        entityManager.flush();
        entityManager.clear();
        commit();
        return mergedEntity;
    }

    @SuppressWarnings({"unchecked"})
    public T find(int entityID) {       
        return (T) entityManager.find(entityClass, entityID);
    }

    @SuppressWarnings({"unchecked"})
    public T findReferenceOnly(int entityID) {
        return (T) entityManager.getReference(entityClass, entityID);       
    }

    // Using the unchecked because JPA does not have a
    // em.getCriteriaBuilder().createQuery()<T> method
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public List<T> list() {
        CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return entityManager.createQuery(cq).getResultList();
    }

    // Using the unchecked because JPA does not have a
    // query.getSingleResult()<T> method
    @SuppressWarnings("unchecked")
    protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
        T result = null;

        try {
            Query query = entityManager.createNamedQuery(namedQuery);

            // Method that will populate parameters if they are passed not null and empty
            if (parameters != null && !parameters.isEmpty()) {
                populateQueryParameters(query, parameters);
            }

            result = (T) query.getSingleResult();

        } catch (NoResultException e) {
            System.out.println("No result found for named query: " + namedQuery);
        } catch (Exception e) {
            System.out.println("Error while running query: " + e.getMessage());
            e.printStackTrace();
        }

        return result;
    }

    private void populateQueryParameters(Query query, Map<String, Object> parameters) {
        for (Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
    }       
}

更新2

这就是我如何从存储库中获取所有类别

public TreeNode getRoot() {
    if (root == null) {
        List<ICategoria> listaCategorias = repositorio.getCategoriaList();

        root = new DefaultTreeNode(null);
        TreeNode noInicial = new DefaultTreeNode("Categorias", root);

        for (ICategoria categoria : listaCategorias) {
            if (categoria.getCategoria() == null) {
                TreeNode node = new DefaultTreeNode(categoria, noInicial);
                incluirNoFilho(categoria, node);
            }
        }
    }
    return root;
}

感谢您的时间和答案

2 个答案:

答案 0 :(得分:0)

直接发布有关merge

的JPA 2.0文档
The persistence provider must not merge fields marked LAZY that have not been fetched: it must ignore
such fields when merging.

由于您的文档是LAZY LOADED,您将首先使用主实体获取它们,否则将忽略对集合所做的更改。但是,我很好奇为什么它不起作用因为你应该从中获取集合(LAZY WAY)从中删除一些实体,因此集合应该由代理提取。您能否告诉我们您获取和操作此类集合的代码?

答案 1 :(得分:0)

经过多次研究后我发现了问题,我意识到在注释中我错过了

(orphanRemoval=true)

所以现在我的代码看起来像这样

@OneToMany(targetEntity=Categoria.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="categoria")
private List<ICategoria> categoriaList;

这是解决方案