Eu vim do PHP e não tenho muita experiência com hibernate e estou com um problema no relacionamento entre tabelas,
Não posso mostrar as tabelas aqui da empresa então criei uma situação parecida com a daqui, a situação fictícia é um controle de consumo de créditos de ligações telefonicas de vários clientes:
Eu possuo a seguinte estrutura de banco de dados: (modelo1.png)
//Retirei os getters e setters para não ocupar muito espaço.
public class Cliente {
@Id
@GeneratedValue
private Long id;
private String cnpj;
private String nome;
@ManyToOne
@JoinColumn(name="cliente_pai_id")
private Cliente clientePai;
}
public class Contrato implements DomainObject {
@Id
@GeneratedValue
private Long id;
@NotEmpty
private String numero;
@ManyToOne
@JoinColumn(name="cliente_id")
private Cliente cliente;
}
public class Credito implements DomainObject {
@Id
@GeneratedValue
private Long id;
private Long quantidade;
@ManyToOne
@JoinColumn(name="contrato_id")
private Contrato contrato;
@ManyToOne
@JoinColumn(name="tipo_id")
private Tipo tipo;
@NotNull
@ManyToOne
@JoinColumn(name="cliente_id")
private Cliente cliente;
}
public class Tipo implements DomainObject {
@Id
@GeneratedValue
private Long id;
private String nome;
private Long creditosPorMinuto;
}
As seguintes regras:
Um cliente pode ter várias filiais.
Um cliente matriz pode ter um ou vários contratos e as filiais herdam todos os contratos da matriz.
Um cliente filial pode ter seu próprio contrato que não pode ser visto pela matriz.
Um contrato deve definir a quantidade máxima de créditos que podem ser contratados por tipo de crédito, matriz e filial(filiais podem ter limite diferente da estabelecida pela matriz).
O crédito pode ser transferido entre a filial e matriz, quando a matriz transfere créditos para uma filial, conta como se tivesse utilizado pela matriz.
Do jeito que esta funciona até certo ponto, pois não consigo trazer todos os clientes que utilizam o contrato 1 por exemplo, pois a tabela contrato não esta relacionada com os clientes filhos diretamente, somente pela tabela créditos. Não sei se a causa é falta de relacionamento bidirecional, mas deixo esta como última opção pois não sei o impacto de performance que isto causaria.
Acho que meu problema esta na abstração dos objetos, podem me ajudar?
De preferência preciso seguir esta estrutura de tabela, mas se não tiver jeito posso redesenha-los.
Acho que eu tentei detalhar demais e acabei complicando.
Resumindo:
Um contrato tem um dono (matriz) esse contrato é compartilhado entre as filiais dela e os créditos deste contrato podem ser transferidas para as clientes das filiais.
Não consigo imaginar como fazer o relacionamento entre essas entidades.
Por exemplo, a matriz tem 10 creditos, e transfiro 5 para a filial.
Quando eu pego os creditos da matriz, é só eu executar:
Não lembro exatamente como resolver isso com annotations, mas com HQL ficaria mais ou menos assim:
cr from Credito cr
join cr.contrato c
join cr.cliente cl
join cl.clientePai
where c.id = :paramId
Dessa forma você teria todos os créditos de certo contrato, a partir daí é só acrescentar mais filtros para chegar no nivél de detalhe que você quiser.
Eu tenho uma pagina de clientes, contratos e créditos.
Para verificar os créditos de um determinado cliente, eu abro a página de clientes, e será mostrado uma página de contratos deste cliente (se for cliente filho será mostrado os contratos do pai também) e na página de contratos eu mostro os créditos deste contrato.
Então se eu passo, na url (estou usando spring): cliente/1/contrato/1.html
Na página de contratos eu quero mostrar os dados do contrato e os créditos:
Então terei que fazer?
Contrato contrato = contratoDao.find(1);
List creditos = creditoDao.findByContratoCliente(1,2);
Será que não tem um jeito de relacionar eles pra fazer tipo?
Contrato contrato = contratoDao.find(1);
List creditos = contrato.getCliente(2).getCredito();
Acredito que seja a maneira mais facil através do DAO.
Ou você poderia criar uma relação inversa, onde o cliente tem uma lista de contratos ou creditos…
Daí você precisaria dar uma lida nas anotações @OneToMany e @ManyToOne e o parametro mappedBy
[quote=calel]Acredito que seja a maneira mais facil através do DAO.
Ou você poderia criar uma relação inversa, onde o cliente tem uma lista de contratos ou creditos…
Daí você precisaria dar uma lida nas anotações @OneToMany e @ManyToOne e o parametro mappedBy[/quote]
Cael,
Usei a sugestão do HQL que você tinha falado, mas como estou usando critéria eu joguei a mesma coisa só que no critéria.
A Única coisa que eu achei “feio” é na página de contrato do clientefilho tenho que fazer:
pra criar um link do tipo cliente/(id da empresa)/contrato/(id do contrato). Se eu tivesse usado contrato.getCliente().getId() ele traria o ID do pai e não do filho já que o contrato só se relaciona com o pai.
Mas acho que não da por causa da estrutura das tabelas, pois n tenho uma tabela intermediária tipo ClienteContrato.
Esse negócio de compartilhar contratos entre matriz e filial é muito complicado, ou eu que estou complicando…