Existe uma maneira no JPA de mapear uma coleção de Enums dentro da classe Entity? Ou a única solução é envolver o Enum com outra classe de domínio e usá-lo para mapear a coleção?
@Entity
public class Person {
public enum InterestsEnum {Books, Sport, etc... }
//@???
Collection<InterestsEnum> interests;
}
Estou usando a implementação Hibernate JPA, mas é claro que preferiria uma solução independente de implementação.
java
jpa
jakarta-ee
Gennady Shumakher
fonte
fonte
O link na resposta de Andy é um excelente ponto de partida para mapear coleções de objetos "não Entidade" no JPA 2, mas não está totalmente completo quando se trata de mapear enums. Aqui está o que eu inventei.
fonte
@ElementCollection
eCollection<InterestsEnum> interests;
O resto é potencialmente útil, mas desnecessário. Por exemplo,@Enumerated(EnumType.STRING)
coloca strings legíveis por humanos em seu banco de dados.@Column
estáname
implícito. Eu só queria esclarecer o que está implícito quando @Column é omitido. E @Enumerated é sempre recomendado, já que ordinal é uma coisa horrível para se usar como padrão. :)@CollectionTable(name="person_interest", joinColumns = {@JoinColumn(name="person_id")})
Consegui fazer isso desta maneira simples:
O carregamento rápido é necessário para evitar erros de inicialização de carregamento lento, conforme explicado aqui .
fonte
Estou usando uma pequena modificação de java.util.RegularEnumSet para ter um EnumSet persistente:
Esta classe agora é a base para todos os meus conjuntos de enum:
E esse conjunto posso usar na minha entidade:
Vantagens:
java.util.EnumSet
para obter uma descrição)Desvantagens:
RegularEnumSet
ePersistentEnumSet
são quase iguais)EnumSet.noneOf(enumType)
em seuPersistenEnumSet
, declararAccessType.PROPERTY
e fornecer dois métodos de acesso que usam reflexão para ler e escrever oelements
campo@Embeddable
aPersistentEnumSet
e solte a aula extra (... interests = new PersistentEnumSet<>(InterestsEnum.class);
)@AttributeOverride
, como mostrado no meu exemplo, se tiver mais de umPersistentEnumSet
em sua entidade (caso contrário, ambos seriam armazenados na mesma coluna "elementos")values()
com reflexão no construtor não é o ideal (especialmente quando se olha para o desempenho), mas as outras duas opções também têm suas desvantagens:EnumSet.getUniverse()
faz uso de umasun.misc
classefonte
tl; dr Uma solução curta seria a seguinte:
A resposta longa é que com essas anotações JPA criará uma tabela que conterá a lista de InterestsEnum apontando para o identificador da classe principal (Person.class neste caso).
@ElementCollections especifica onde JPA pode encontrar informações sobre o Enum
@CollectionTable cria a tabela que mantém o relacionamento de Person para InterestsEnum
@Enumerated (EnumType.STRING) diz ao JPA para persistir o Enum como String, poderia ser EnumType.ORDINAL
fonte
As coleções na JPA referem-se a relacionamentos um para muitos ou muitos para muitos e podem conter apenas outras entidades. Desculpe, mas você precisa envolver esses enums em uma entidade. Se você pensar sobre isso, você precisaria de algum tipo de campo de ID e chave estrangeira para armazenar essas informações de qualquer maneira. A menos que você faça algo maluco como armazenar uma lista separada por vírgulas em uma String (não faça isso!).
fonte