我运行了一些DDL脚本来在我的数据库中设置一个完整的国家/地区表。国家/地区表的主键列包含每个国家/地区的相应ISO代码。
在我的JPA项目中,我有一个具有嵌入式地址实体的用户实体,该地址实体具有对国家的引用。用户和地址之间的关系对我来说似乎没问题,但是地址和国家之间的关系。我试图将其映射为ManyToOne关系,因为许多地址可以共享一个国家。
问题是:我使用Id - >注释了Country类的iso成员变量。现在,JPA / Hibernate抱怨没有手动设置国家的ID。但在这种情况下,id已经被赋予并设置,因为我导入了一次数据,ISO代码是唯一的,并且db schema意味着被声明为主键。在这种特殊情况下,国家/地区表中不需要更新或插入 - 信息应该只读!
知道该怎么做,所以我可以使用我的国家表而不改变吗?
答案 0 :(得分:0)
你的问题缺少一些细节,所以以下内容涉及很多猜测:-)
您的Country
课程应该类似于:
@Entity
@Immutable
@Table(name="countries")
public class Country {
@Id
private String isoCode;
// all other attributes, getters / setters, etc...
}
@Immutable
是Hibernate extension到JPA标准;你没有把它放在实体上,但拥有它会导致稍微好一点的性能。请注意,真正使Country
不可变 - 您将无法通过应用程序创建/更新/删除国家/地区。您可能还希望为Country
实体配置cache,如果它经常使用的话。
您的Address
会有以下映射到国家/地区:
@ManyToOne
@JoinColumn(name="country_iso_code")
private Country country;
请注意,没有“级联”属性 - 您不需要任何属性。这里最后一个重点是你实际需要获取或加载Country
实例以在地址上设置它:
Country country = (Country) session.load(Country.class, isoCode);
// OR
Country country = (Country) session.get(Country.class, isoCode);
address.setCountry(country);
...
session.saveOrUpdate(address);
上面的第一行将不点击数据库;如果您知道存在此类ISO代码的国家/地区,请使用它。第二种形式将命中数据库(或缓存,如果已配置),如果不存在具有该代码的国家/地区,则返回NULL。