https://thorben-janssen.com/polymorphic-association-mappings-of-independent-classes/
já vou deixar um salve pro Thorben Janssen autor da postagem acima.
Vou fazer um rascunho desse post, e depois vou evoluindo o assunto rs
A questão é que vi e usei dessa abordagem de uma forma não tão bonita quanto essa do post acima e acho que é até uma case comum no mundo corporativo e como achei a abordagem um tanto complexa, achei que poderia adicionar alguns exemplos, e fazer uma versão minha 😅.
Aqui a base em comum
Basicamente marcamos em algumas tabelas as seguintes colunas ORIGEM_KEY e TIPO_ORIGEM_KEY ambas numéricas (essa parte já estava na empresa quando eu cheguei 😅, no caso teria usado um Enum para a representação de tipo).
Fazíamos isso pois em determinado momento do workflow chegavamos em um funil onde basicamente todas as operações do sistema tinham que ser mapeadas e registradas em um "livro". Contudo em determinados momentos precisamos fazer uma "engenharia reversa" do processo para chegar a origem do registro que poderia ser de qualquer parte do sistema.
Obs: Ai vai a primeira desvantagem do modelo, tem que se quebrar uma das regras de normalização do banco (caso você esteja trabalhando com banco relacional) pois quem vai demarcar a origem ou seja a tabela que contém as informações que em teoria estariam vinculadas via uma FK vai TIPO_ORIGEM_KEY e o registro como é dedutivel será de responsabilidade da ORIGEM_KEY. Você pode vir a adicionar CONSTRAINTS para tentar garantir o mínimo de digamos "consistência" contudo a aplicação que terá que fazer todo o trabalho.
Aqui como costumava usar
@Entity
public class ChessPlayer {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "chess_player_seq")
@SequenceGenerator(name = "chess_player_seq",
sequenceName = "chess_player_seq", initialValue = 100)
private Long id;
private String firstName;
private String lastName;
private Integer wins;
private Integer loses;
...
}
A partir do tipo salvo fica fácil de implementar uma regra que saiba buscar as demais informações necessárias para a sua necessidade. Contudo da minha forma ainda era um cenário verboso e cheios de IFs...
Em contra partida a versão menos verbosa não é tão flexível e na minha opinião torna o código mais acoplado (isso aqui já é minha conclusão).
public enum TipoOrigem {
TIPO_1(1,Repository1.class), TIPO_2(2,Repository2.class);
private final int key;
private final Class<T> clazz;
public TipoOrigem(int key ,Class<T extends Repository> clazz){
key = key;
clazz = clazz
}
public static Map<Integer, Class<T extends Repository>> getMap(){
return ...
}
}
Coloquei uma exemplificação que precisa ser melhorada Rs
Mas basicamente segue uma strategy que tem como base a key da relação como chave de seleção.
A partir dela podemos buscar a informação de onde acharmos conveniente.
Top comments (0)