1

我运行了一些 DDL 脚本来在我的数据库中设置一个完整的国家/地区表。国家表的主键列包含每个国家对应的 ISO 代码。

在我的 JPA 项目中,我有一个具有嵌入式地址实体的用户实体,并且该地址实体具有对国家/地区的引用。User 和 Address 之间的关系对我来说似乎没有问题,但是 Address 和 Country 之间的关系。我试图将其映射为多对一关系,因为许多地址可以共享一个国家。

问题是:我用 Id 注释了 Country 类的 iso 成员变量 -> 现在,JPA/Hibernate 抱怨没有手动设置国家的 id。但是在这种情况下,已经给出并设置了 id,因为我导入了一次数据并且 ISO 代码是唯一的,并且通过 db 模式表示声明为主键。在这种特殊情况下,不需要在国家/地区表中更新或插入 - 信息应该是只读的!

知道该怎么做,所以我可以使用我的国家表而不改变?

4

1 回答 1

0

您的问题缺少一些细节,因此以下涉及很多猜测:-)

你的Country班级应该是这样的:

@Entity
@Immutable
@Table(name="countries")
public class Country {
  @Id
  private String isoCode;
  // all other attributes, getters / setters, etc...
}

@Immutable是JPA 标准的Hibernate 扩展;不必将它放在实体上,但拥有它会带来更好的性能。请记住,它确实会使Country不可变 - 您将无法通过您的应用程序创建/更新/删除国家/地区。如果经常使用它,您可能还想为您的实体配置缓存。Country

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。

于 2009-11-17T20:19:36.747 回答