Olá pessoal venho por meio deste pedir ajuda para um entendimento, a situação é a seguinte tendo uma tree do primeFaces, simples em primeira vista tendo duas categorias pais, que não podem ser alteradas e os filhos, até ai tudo bem, o que não consigo entender é o relacionamento com o Hibernate, pensei em uma lógica sem o Hibernate e consegui concretizar o pensamento de forma com que eu entendesse mas essa entidade do livro está realmente complicado.
package financeiro.categoria;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import financeiro.usuario.Usuario;
@Entity
public class Categoria implements Serializable {
@Id
@GeneratedValue
private Integer codigo;
@ManyToOne
@JoinColumn(name = "categoria_pai", nullable = true)
@org.hibernate.annotations.ForeignKey(name = "fk_categoria_categoria")
private Categoria pai;
@ManyToOne
@OnDelete(action=OnDeleteAction.CASCADE)
@JoinColumn(name = "usuario")
@org.hibernate.annotations.ForeignKey(name = "fk_categoria_usuario")
private Usuario usuario;
private String descricao;
private int fator;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
@JoinColumn(name = "categoria_pai", updatable = false)
@org.hibernate.annotations.OrderBy(clause = "descricao asc")
private List<Categoria> filhos;
public Categoria() {
}
public Categoria(Categoria pai, Usuario usuario, String descricao, int fator) {
this.pai = pai;
this.usuario = usuario;
this.descricao = descricao;
this.fator = fator;
}
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public Categoria getPai() {
return pai;
}
public void setPai(Categoria pai) {
this.pai = pai;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public List<Categoria> getFilhos() {
return filhos;
}
public void setFilhos(List<Categoria> filhos) {
this.filhos = filhos;
}
public int getFator() {
return fator;
}
public void setFator(int fator) {
this.fator = fator;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((codigo == null) ? 0 : codigo.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Categoria other = (Categoria) obj;
if (codigo == null) {
if (other.codigo != null)
return false;
} else if (!codigo.equals(other.codigo))
return false;
return true;
}
}
Alguém pode me explicar como funciona aquelas chaves externas, sei que existe o relacionamento dos filhos com os pais o que ajuda na hora da exclusão de uma categoria seus filhos sejam excluidos também, mas a existencia das outras chaves está dificil de entender. Se alguém se dispuser a explicar como elas se formam e onde são usadas.
Olá Mathe, tenho esse livro e fiz também esse projeto, então é assim mesmo. Nesse caso a classe categoria tem relacionamento com ela mesmo (auto-relação), isso porque uma categoria pode ter subcategorias relacionada a ela. Na primeira vez que a categoria for criada ela não terá pai, porém pode ter categorias associadas a ela.
A explicação que vc quer está na classe de regra de negocio onde mostra a relação do objeto Categoria pai.
[quote=satangoss]Olá Mathe, tenho esse livro e fiz também esse projeto, então é assim mesmo. Nesse caso a classe categoria tem relacionamento com ela mesmo (auto-relação), isso porque uma categoria pode ter subcategorias relacionada a ela. Na primeira vez que a categoria for criada ela não terá pai, porém pode ter categorias associadas a ela.
A explicação que vc quer está na classe de regra de negocio onde mostra a relação do objeto Categoria pai. [/quote]
pode ver que na tabela categoria tem um campo fk_categoria_categoria que referencia outra Categoria, que pode ser nula caso a categoria for a categoria do topo da hierarquia.
[quote=Mathe] Hmm, isso é o que as manteria unida para no caso de exclusão o efeito cascade ser utilizado?
E nos outros casos como o da foreign key do usuario?[/quote]
caso o usuário for excluido, serão excluidas as categorias relacionadas a ele como mostra aqui:
Não, o que indica é que a classe categoria tem um objeto do tipo Usuario, ou muitas categorias para um usuario (ManyToOne) por isso toda vez que um usuário for excluido o hibernate verifica se o mesmo tem alguma dependencia de Categoria, justamente por causa da anotação @OnDelete(action=OnDeleteAction.CASCADE) no Objeto :
private Usuario usuario;
nao vai ter nenhuma menção a filho na tabela Categoria e sim a coluna categoria_pai, ou seja toda categoria que tiver categoria_pai != null será categoria filha, as categorias que nao tiverem categoria_pai serão as categorias superiores no caso DESPESA e RECEITA.
Nossa velho talvez eu tenha dificultado mais do que o necessario, vc pode me dizer se o meu pensamento agora está correto, quando utilizado o atributo List filhos; está se utilizando uma nova instancia de categoria que tera esse ligado a um pai na categoria_pai e quando esse pai for chamado chamara todos os filhos, se não for isso vou queimar o livro -
Sim, realmente entendi o que acontece só foi estranho pra min o fato dos filhos ficarem somente ligados a um pai e quando esse pai for chamado aparecerem, e não ficarem “fisicamente” armazenados na tabela.
Repare que RECEITAS E DESPESAS, nao tem pai, portanto são categorias de nó Rais (Topo da hierarquia),
Alimentação é categoria filha de DESPESAS e ao mesmo tempo pai da Categoria Restaurante e Mercado.
A categoria mensalidade é categoria do tipo folha da arvore pq é filha de Internet que é fila de DESPESAS mas não tem nenhuma categoria com ela como pai.