1. java
  2. android
  3. c#
  4. .net
  5. javascript
  6. php
  7. jquery
  8. html
  9. sql

Busca Many-to-Many em HQL - Resolvido

Não precisei fazer HQL para esse caso.

Como estava fazendo Many-to-many com uma tabela associativa, coloquei one-to-many e a que nao precisava que nao ia realizar consulta dela para a outra classe, eu deixei como @transient

a aplicação ficou 10 vezes mais rapida.


Tenho um projeto tipo WIKI, tenho varias solucões (sao perguntas e respostas), e as buscas sao feitas por tags, o relacionamento delas (Many-to-Many), e para Solução existe varias tag`s. Mas a busca tem demorado muito da forma que foi implementada.

Umas das formas de deixar a busca mais rapida foi deixar a relacao Solucao - TAG como @Transient, mas com isso, a ligação se perde e tenho que realizar uma busca com HQL para suprir essa necessidade. ALguem pode ajudar?

Tenho duas entidades, o relacionamento entre elas sao Many-to-Many.

Solucao

@Entity
@Table(name = "tSolucao")
public class Solucao extends AbstractBean {

    private static final long serialVersionUID = 1L;

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

    @Column(length = 250)
    private String titulo;

    @Column(length = 4000)
    private String questionario;

    @Column(length = 8000)
    private String solucao;

    @Temporal(TemporalType.TIMESTAMP)
    private Date dataCriacao;

    @Temporal(TemporalType.DATE)
    private Date expiraEm;

    @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.REFRESH)
    @JoinTable(name = "tSolucaos_tTags", joinColumns = { @JoinColumn(name = "idSolucao") }, inverseJoinColumns = { @JoinColumn(name = "idTag") })
    @Transient
    private List<Tag> tags;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "idOrigem")
    private Origem origem;

    @Column(length = 15)
    private String numeroChamado;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "idArquivoSolucao")
    private ArquivoSolucao arquivoSolucao;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "idStateSolucao")
    private StateSolucao stateSolucao;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "tFavorito_Tsolucao", joinColumns = { @JoinColumn(name = "idSolucao") }, inverseJoinColumns = { @JoinColumn(name = "idFavorito") })
    private List<Favorito> favoritos;

         //GET e SET

TAG

@Entity
@Table(name = "tTag")
public class Tag extends AbstractBean {

    private static final long serialVersionUID = 1L;

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

    @Column(length = 80, unique = true)
    private String tag;

    @Column(length = 200)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataCriacao;

    @Column(nullable = true)
    @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.REFRESH)
    @JoinTable(name = "tSolucaos_tTags", joinColumns = { @JoinColumn(name = "idTag") }, inverseJoinColumns = { @JoinColumn(name = "idSolucao") })
    @Transient
    private List<Solucao> solucoes;

    @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinColumn(name = "idTipoTag")
    @OrderBy("idTipoTag")
    private TipoTag tipoTag;

    public Tag() {
    }

    public Tag(String tag, Date dataCriacao) {
        super();
        this.tag = tag;
        this.dataCriacao = dataCriacao;
    }

      // GET e SET...

Agora tenho uma service que recebe do Flex a solicitacoes para realizar a busca:

@Service(value = "SolucaoService")
@RemotingDestination
public class SolucaoService extends AbstractService {

@Resource
private DAO<Solucao, Integer> daoSolucao;


@RemotingInclude
public List<Solucao> getSolucoesByTags(String matricula, List<Tag> tags) {

        Integer tagsIDS[] = new Integer[tags.size()];
        for (Tag tag : tags) {
        tagsIDS[tags.indexOf(tag)] = tag.getIdTag();
    }

    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Solucao.class);
    detachedCriteria.createCriteria("tags").add(Restrictions.in("idTag", tagsIDS));
    detachedCriteria.createCriteria("stateSolucao").add(Restrictions.eq("idStateSolucao", new Integer(2)));
    detachedCriteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
    List<Solucao> solucoes = daoSolucao.getAllEntities(Solucao.class,  detachedCriteria);
        return solucoes;
}


}

Possivel solucao, mas não tem funcionado como esperado:

@Service(value = "SolucaoService")
@RemotingDestination
public class SolucaoService extends AbstractService {

@Resource
private DAO<Solucao, Integer> daoSolucao;


@RemotingInclude
public List<Solucao> getSolucoesByTags(String matricula, List<Tag> tags) {

        Integer tagsIDS[] = new Integer[tags.size()];
        for (Tag tag : tags) {
        tagsIDS[tags.indexOf(tag)] = tag.getIdTag();
    }


    String query = "from Solucoes solucao join Tag where Solucao in elemensts(?1) group by Solucao";
        query.setString(1, tags);
        List<Solucao> solucoes = daoSolucao.find(query, tagsIDS);
        return solucoes;

}


}
  • Talvezzzz... O Paradigma Relacional não seja o mais indicado para o seu caso... Nunca usei NoSQL para nada, mas, caso ainda seja possível, você poderia tentar algo com MongoDB...

    Marcio Rodrigues   17 de mai de 2013
  • Mas esse e o meu caso. preciso custimizar essa ligacao. isso que esta complicado

    wellison   17 de mai de 2013
  • não altere o titulo para resolvido, marque a resposta correta...

    Cristian Urbainski   18 de mai de 2013
  • Mas nao teve ninguem que respondeu corretamente. Eu mesmo descobri o problema e postei a solucao aqui.

    wellison   18 de mai de 2013
  1. Você vai ver essas setas em qualquer página de pergunta. Com elas, você pode dizer se uma pergunta ou uma resposta foram relevantes ou não.
  2. Edite sua pergunta ou resposta caso queira alterar ou adicionar detalhes.
  3. Caso haja alguma dúvida sobre a pergunta, adicione um comentário. O espaço de respostas deve ser utilizado apenas para responder a pergunta.
  4. Se o autor da pergunta marcar uma resposta como solucionada, esta marca aparecerá.
  5. Clique aqui para mais detalhes sobre o funcionamento do GUJ!

1 resposta

Não é a resposta que estava procurando? Procure outras perguntas com as tags flex hibernate performance sql ou faça a sua própria pergunta.