Tenho um modelo de dados em que algumas entidades heram atributos comuns de uma superclasse. Estou usando InheritanceType.JOINED, em que o hibernate/jpa cria uma tabela para os atributos da superclasse (Fornecedor) e tabelas contendo somente os atributos adicionados pelas subclasses (FornecedorHotel e FornecedorDiversos). Até aí, tudo bem.
O problema surge quando eu tento inserir um FornecedorHotel (fornece serviço de hospedagem) que é também um FornecedorDiversos (fornece aluguel de salas, serviço de buffet, etc). O fornecedorHotel é inserido sem problemas, sendo os dados basicos inseridos na tabela Fornecedor (superclasse) e os dados especificos inseridos na tabela FornecedorHotel (subclasse). No momento de inserir os dados especificos de FornecedorDiversos (outra subclasse) ocorre o erro, pois o hibernate tenta inserir novamente na tabela Fornecedor ocorrendo violação de PK.
Existe alguma forma de instruir o hibernate/jpa a inserir somente os dados especificos na tabela FornecedorDiversos? Ele deveria entender que a superclasse já possui o ID em questão e inserir somente os dados especificos na subclasse, mas ele não faz isso. Alguém já passou por algo parecido?
Seguem os pseudo-códigos para análise:
Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Fornecedor implements Serializable {
private Long id;
private String nome;
private String email;
private Long cnpj;
private Boolean ativo;
// getters e setters
}
@Entity
@Table(name="FORNECEDOR_HOTEL")
@Inheritance(strategy=InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name="ID_FORNECEDOR")
public class FornecedorHotel extends Fornecedor {
private Date dataCadastro;
private String tipoApartamento;
private Integer tipoQuarto; // 1 - single, 2 - double, 3 - triple, 4 - quadruple
private Integer tipoCama; // 1 - solteiro, 2 - casal
private Set<TipoProduto> produtos = new HashSet<TipoProduto>(0);
//getters e setters
}
@Entity
@Table(name="FORNECEDOR_DIVERSOS")
@Inheritance(strategy=InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name="ID_FORNECEDOR")
public class FornecedorDiversos extends Fornecedor {
private Date dataCadastro;
private Set<TipoProduto> produtos = new HashSet<TipoProduto>(0);
//getters e setters
}
public class App {
public static void main(String[] args) {
...
Map<String, Set<TipoProduto>> mapaTiposProdutos = prepararProdutos(produtosEJB);
Set<TipoProduto> tiposProdutoHotel = mapaProdutos.get("HOT");
Set<TipoProduto> tiposProdutoDiversos = mapaProdutos.get("DIV");
FornecedorHotel hot = new FornecedorHotel();
hot.setId(new Long(1));
hot.setNome("FORNECEDOR_001");
hot.setEmail("[email removido]");
hot.setCnpj(123456789l);
hot.setDataCadastro(data.getTime());
hot.setAtivo(Boolean.TRUE);
hot.setTipoApartamento("LUXO");
hot.setProdutos(tiposProdutoHotel );
fornecedorEJB.cadastrarFornecedorHotel(hot); //ok
FornecedorDiversos diversos = new FornecedorDiversos();
diversos.setId(new Long(1));
diversos.setDataCadastro(data.getTime());
diversos.setProdutos(tiposProdutoDiversos );
fornecedorEJB.cadastrarFornecedorDiversos(diversos); //erro - tanto chamando persist quanto merge...
}
}