Hibernate self-join (dúvida)

Boa tarde pessoal,

Tenho uma tabela (Tag) com auto-relacionamento que aponta para um registro pai (TagId PK, ParentTagId FK)

Tenho a classe abaixo mapeada por annotations e funcionando corretamente (consigo retornar as Tags e o seu ‘parent’)

[code]
@Entity
@Table(name=“SearchTag”)
public class SearchTag {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name=“TagId”)
public long getTagId() {
return tagId;
}
public void setTagId(long tagId) {
this.tagId = tagId;
}
private long tagId;

@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinColumn(name="ParentTagId")
public SearchTag getParentTag() {
	return parentTag;
}
public void setParentTag(SearchTag parentTag) {
	this.parentTag = parentTag;
}
private SearchTag parentTag;

}[/code]

Meu problema é o seguinte: qual a melhor forma para eu implementar metodo que retorne uma Collection com as tags filhas de uma determinada tag? Com sql seria simplesmente um select * from tag where parenttagid = ?, mas estou pensando em como fazer isso mapeando com annotations…seria possivel?

Obrigado

http://www.guj.com.br/java/250593-jpa-auto-relacionamento---onetomany#1301724

Obrigado pela resposta, eu desconfiava que deveria alterar a estrutura mesmo =/

Optando pela solução do link, devo remover o campo parentTagId da tabela Tag, correto?

Qual a estrutura de suas tabelas?

Tabela principal:

Tag (tagId (PK), parentTagIg (FK), tagName, …)

Tabela criada para atender o modelo indicado:
TagChildren (tagId (fk), childTagId(fk)) - as duas fks apontando para a tabela principal.

Obrigado

Você está correto, não é mais necessário a coluna parentTagIg.

Abraços.

[quote=clunsde]Você está correto, não é mais necessário a coluna parentTagIg.

Abraços.[/quote]

Caro clunsde,

Na minha classe SearchTag, criei a collection abaixo

@XmlTransient @OneToMany( targetEntity=org.ecmlib.core.entity.SearchTag.class, cascade={javax.persistence.CascadeType.ALL, javax.persistence.CascadeType.MERGE}, fetch=FetchType.LAZY ) @JoinTable( name="SearchTagChildren", joinColumns=@JoinColumn(name="ParentTagId"), inverseJoinColumns=@JoinColumn(name="ChildTagId") ) private Collection<SearchTag> childrenTags; public Collection<SearchTag> getChildrenTags() { return childrenTags; } public void setChildrenTags(Collection<SearchTag> tagList) { this.childrenTags = tagList; }

Está funcionando como eu gostaria inicialmente, porém o que estou tentando agora é fazer com que essa collection fique com o comportamento “Lazy” (carregada apenas quando eu chamar o getter dessa collection)

Com o código acima, não estou conseguindo…sempre que carrego uma SearchTag pelo Id, essa collection é carregada automaticamente =/

Saberia me dizer o que fazer?

Algumas questões

quando você usa

isso já inclui o javax.persistence.CascadeType.MERGE

Outra questão, a tag pai não poderia ser filha de outra tag?

Obrigado pela dica.

A resposta para a segunda pergunta é: sim. A idéia é que qualquer tag possa ser filha de outra tag, logo uma tag que possui filhos, pode ser filha de outra tag.

Att.

Se a resposta é sim, então a relação seria @ManyToMany e não @OneToMany.

Abraços.

[quote=clunsde]Se a resposta é sim, então a relação seria @ManyToMany e não @OneToMany.

Abraços.[/quote]

Entendido, realmente faz sentido…eu já fiz relacionamentos ManyToMany, mas entre entidades diferentes: mapeando no owner e usando o atributo mappedBy na outra extremidade (neste caso o lazy load funciona corretamente)

Gostaria de saber como fazer o lazy load no meu caso, onde existe um auto relacionamento (eu devo esta mapeando algo errado).

Obrigado pela ajuda.

Mostre como ficou o código final, para eu tentar te ajudar. No caso de collections, é sempre Lazy … não sei realmente o que pode estar acontecendo.