例如,我们有一个Shops表。每个商店属于某个国家(现在实施为ENUM)。现在我需要将商店不仅映射到一个国家,还要映射到该国家的某个地区。
第一个想法是制作单独的表国家和地区。国家有很多地区,商店属于一个地区,并通过它到国家。但是如果我需要能够将Shop映射到一个国家而不指定它的区域呢?用我的解决方案是不可能的。
第二个想法是使用复杂的ENUM。像这样:
public enum Location implements ContainsRegion {
FRANCE("France") {
public EnumSet getRegions() {
return EnumSet.allOf(FranceRegions.class);
}
},
GERMANY("Germany") {
public EnumSet getRegions() {
return EnumSet.allOF(GermanyRegions.class);
}
};
private final String country;
private Region region;
public static Location factory(String name) throws IOException {
for(Location c : values()) {
if(c.country.equalsIgnoreCase(name)) {
return c;
}
}
throw new IOException("Unknown country");
}
@JsonCreator
public static Location factory(@JsonProperty("region") Region region, @JsonProperty("name") String name) throws IOException {
Location location = factory(name);
if(isNull(region)) {
return location;
}
if(location.getRegions().contains(region)) {
location.setRegion(region);
return location;
}
throw new IOException("This region is not available for location");
}
}
它适用于JSON序列化和反序列化,但我无法将其映射到db表?这有什么解决方案吗?
最后一个想法是创建一个单独的实体位置:它将包含对商店,国家和地区的引用。并将映射到Shop为@OneToOne。在这种情况下,它从Shop实体到Location实体我将能够获取/设置国家和地区,如果未指定region,则它可能只是null。
请告诉我,完成此任务的最佳方法是什么?谢谢!
这是不可能的,你在使用带有JPA的枚举时应该三思而后行。
请阅读我关于该主题的文章:https://martinelli.ch/2018/01/08/mapping-enums-with-jpa/
目前JPA 2.1不支持映射枚举包含的变量。我认为第一个解决方案是正确的,在Shop内部建立一个ManyToOne关系,并在Region和country之间建立一个oneToOne关系(因此国家将热切地加载Region,你可以随时访问它),你也可以提供一个区域内的便捷方法,提供国家/地区的名称或任何方便您的业务的地区