Eu acho que entendi o que você quer fazer. Mas tenho uma dúvida: o seu modelo de negócio realmente precisa de herança? Se você deixar de lado o banco de dados e modelar o seu sistema com um diagrama de classes, você modelaria uma herança ou uma associação simples? Algo que pode te ajudar é fazer a seguinte pergunta: Existem múltiplas classes que podem estender ArticleModel, ou é apenas uma?
Estou fazendo a pergunta porque talvez existam outras soluções que não sejam a herança. Mas assumindo que herança é mesmo o que você precisa, então vai ter um probleminha que você vai ter que resolver com o modelo que você descreveu. Imagine que você tem a tabela TB_ARTICLE_MODEL
e várias outras tabelas a "estendendo", como o banco de dados saberia qual a tabela de extensão para cada registro na tabela TB_ARTICLE_MODEL
? A solução escolhida pelo time do JPA foi criar um atributo para fazer a distinção. Aqui fica um exemplo que eu fiz:
Note o atributo tb_article_model.proj_type
vai ser usado para saber qual a tabela de extensão.
create table tb_article_model (
article_code uuid not null,
proj_type varchar(31) not null,
article_name varchar(255),
primary key (article_code)
)
create table tb_products_in_stock (
weigth float(53),
article_code uuid not null,
primary key (article_code)
)
alter table if exists tb_products_in_stock
add constraint FKdx5614f3luj74nb5m7nf4kd5s
foreign key (article_code)
references tb_article_model
O codigo fica assim:
@Entity
@Table(name = "TB_ARTICLE_MODEL")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="PROJ_TYPE")
public class ArticleModel {
@Id
private UUID articleCode;
private String articleName;
}
@Entity
@Table(name = "TB_PRODUCTS_IN_STOCK")
@DiscriminatorValue("PRODUCT_MODEL")
public class ProductModel extends ArticleModel {
private Double weigth;
}
@SpringBootTest
public class Heranca {
@Autowired
private ArticleRepository articleRepository;
@Test
void test() {
var p = new ProductModel();
p.setArticleCode(UUID.randomUUID());
p.setArticleName("Meu nome");
p.setWeigth(100d);
articleRepository.save(p);
}
}
O SQL de insercao ficaria assim:
Hibernate:
insert
into
tb_article_model
(article_name,proj_type,article_code)
values
(?,'PRODUCT_MODEL',?)
Hibernate:
insert
into
tb_products_in_stock
(weigth,article_code)
values
(?,?)
Espero ter ajudado.
Mas tenho uma dúvida: o seu modelo de negócio realmente precisa de herança?
Na verdade não, meu conhecimento ainda é bem limitado, por isso me pareceu o melhor caminho. Tentei fazer agora por composição, apesar de fazer total sentido, não havia pensado nisso até lembrar que o Deschamps falou tocou no assunto em um dos vídeos que assiste a alguns meses. Lembrei do termo logo depois que te respondi e fui ler sobre o conceito. Usei, deu um erro na hora de subir a aplicação: Could not determine recommended JdbcType for Java type 'dev.tadeupinheiro.apistockinputspringboot.models.ArticleModel
Não sei significa alguma coisa sem ter as classes da aplicação para entender, mas enfim, mesmo que eu consiga resolver esse erro, não acho que seria performático, salvar todas as classes em cada registro que eu fizer no db.
Vamos lá, vou tentar explicar como funciona o negócio:
Existe os ARTIGOS, que seríam os "modelos" do produto. Exemplo: Existe o artigo chamado UNIPACIFIC, que é um tipo de tecido, que tem seus atributos (nome, peso, fabricante e composição), ele não vai ser alterado, vai ser cadastro e fica lá, eventualmente se cadastraria outros artigos, mas seria em outro métodos, essa parte seria "fácil".
Existe também as CORES, o artigo UNIPACIFIC tem sua paleta de cores, que serve para ele a para outros artigos também. Se encaixa no mesmo esquema: eventualmente se cadastria outros mas não é o centro da api no momento.
Por fim, existe o ROLO, que é o ponto central aqui. O rolo possui o número(que seria o ID dele), possui tamanho, qualidade, tratamento, preço de custo e etc. A questão é que o rolo não se repete e não seria extendido por nenhuma outra classe. Terá a entrada no banco de dados e na venda teria a saída e o id não se repete. Mas o rolo também terá o artigo e seus atributos e a cor e seus atributos, exemplo: Número do rolo: 156879 (primary key) Tamanho: 100m Preço de custo: 19,00 Artigo: Unipacific Fabricante: Satanense (demais atributos do artigo) Código da cor: 5890 Cor: Azul
Então a minha intenção seria:
Salvar o rolo e seus atributos na tabela: TB_PRODUCTS_IN_STOCK, e nele ter a coluna de chave estrangeira fazendo referência para o artigo e a cor. Não salvando a classe completa dentro da tabela como seria na composição. Seria somente a referência e na hora de puxar o relatório puxar pela chave.
Caso faça diferença e possa dar uma olhada:
Repositório GITHUB: https://github.com/tadeupinheiro/api-stock-input-spring-boot/tree/Using-composition/src/main/java/dev/tadeupinheiro/apistockinputspringboot
Está na branch: Using-Composition