Query em mapeamento many to many

5 respostas
bernardon1

olá a todos

tenho as seguintes classes

1- resource

@Entity(name = "resources")
public class Resource {
   
   
    @Id                                     
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(name = "name")
    private String name;
(...)

    /**

2- humanresource

@Entity(name = "humanresources")
public class HumanResources {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
 
    private int profile;
    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "hres")
    private List<Resource> listOfResources; 
(...)

Estou usando o MySQl e ele gera para mim uma tabela humanresource_resource.

pois bem no meu DAO eu tento acessar a tabela associativa.

public static List<Resource> getAllRestrictUpdate(int id) {
        List lisfOfEntities = null;
        List<Resource> project = new ArrayList<Resource>();
        EntityManagerFactory emf = javax.persistence.Persistence.createEntityManagerFactory("spider_mplan");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
      
        lisfOfEntities = em.createQuery("select a from humanresource_resource a").getResultList();
        em.getTransaction().commit();  
        em.close();
        emf.close();

        for (int i = 0; i < lisfOfEntities.size(); ++i) {
            project.add((Resource) lisfOfEntities.get(i));
        }
        return project;
    }

Eu tento acessar de qualquer maneira essa tabela gerada e aparece uma exception dizendo "is not mapped".

Se alguem puder me ajudar e dz como faço para acessar tal tabela ficaria grato, preciso muito usar uma query com a tabela associativa.

5 Respostas

C

Bernardon1,

Este método irá retornar um objeto HumanResources com o id passado no parâmetro e a lista de objetos Resources na variável listOfResources.

public HumanResources getHumanResources(Long idHumanResources) {   
  
  HumanResources hr = null;
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("spider_mplan");   
  EntityManager em = emf.createEntityManager();   
  EntityTransaction et = null;   
  try {   
    et = em.getTransaction();   
    et.begin();   
    StringBuffer sql = new StringBuffer();   
    sql.append(" FROM HumanResources hr ");   
    sql.append(" LEFT JOIN FETCH hr.listOfResources ");   
    sql.append(" WHERE hr.id = :id ");   
  
    Query q = em.createQuery(sql.toString());   
    q.setParameter("id", idHumanResources);   
    hr = q.getSingleResult();   
    et.commit();   
  } catch(Exception ex) {   
    ex.printStackTrace();   
  } finally {   
     if (et != null && et.isActive()) {   
       et.rollback();   
    }   
    if (em != null && em.isOpen()) {   
      em.close();   
    }   
  }   
  return hr;   
}

@braços,

bernardon1

eu preciso que retorne uma lista de Resource a partir do objeto Human Resource, nesse left join eu terei o objeto Human Resource e não o Resource.

Como faço?

Agradeço desde já pela tua ajuda

Abrçs

C

bernardon1:
eu preciso que retorne uma lista de Resource a partir do objeto Human Resource, nesse left join eu terei o objeto Human Resource e não o Resource.

Como faço?

Agradeço desde já pela tua ajuda

Abrçs

Bernardon1,

Basta vc trocar uma pela outra, já que o relacionamento é many-to-many.

public Resource getResources(Long idHumanResources) {     
     
  List humanResources = new ArrayList();
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("spider_mplan");     
  EntityManager em = emf.createEntityManager();     
  EntityTransaction et = null;     
  try {     
    et = em.getTransaction();     
    et.begin();     
    StringBuffer sql = new StringBuffer();     
    sql.append(" FROM Resource r ");     
    sql.append(" LEFT JOIN FETCH r.humanResources hr");     
    sql.append(" WHERE hr.id = :id ");     
     
    Query q = em.createQuery(sql.toString());     
    q.setParameter("id", idHumanResources);     
    humanResources = q.getResultList();     
    et.commit();     
  } catch(Exception ex) {     
    ex.printStackTrace();     
  } finally {     
     if (et != null && et.isActive()) {     
       et.rollback();     
    }     
    if (em != null && em.isOpen()) {     
      em.close();     
    }     
  }     
  return humanResources;     
}

@braços

bernardon1
1. @Entity(name = "resources")  
    public class Resource {  
       
       
      @Id                                       
      @Column(name = "id")  
      @GeneratedValue(strategy = GenerationType.AUTO)  
      private long id;  
      @Column(name = "name")  
   private String name;  
   (...)  
  /**

na minha classe Resource eu não tenho nenhum atributo que possa relacionar o Human Resource portanto o left join fica comprometido de ser feito ( pois tem r.humanresources), eu tenho de criar uma váriavel nessa classe que faça referencia ao Human Resource?

Abrçs

Obrigado novamente

C

Bernardon1,

Deve ser algo assim:

public class Resource {

    ...

    @ManyToMany(fetch = FetchType.EAGER, targetEntity = HumanResources.class,
                cascade = { CascadeType.REMOVE, CascadeType.MERGE,
                            CascadeType.REFRESH })
    @JoinTable(name = "humanresource_resource",
               joinColumns = { @JoinColumn(name = "id_resource") },
               inverseJoinColumns = { @JoinColumn(name = "id_human_resource") },
               uniqueConstraints =
               { @UniqueConstraint(columnNames = { "id_resource", "id_human_resource" }) })
    private Set<HumanResources> humanResources;

    ...

}

public class HumanResources {

    ...


    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE },
                mappedBy = "humanResources",
                targetEntity = Resource.class)
    private Set<Resource> resources;

    ...

}

@braços

Criado 21 de abril de 2010
Ultima resposta 21 de abr. de 2010
Respostas 5
Participantes 2