我正在使用EJB3.2和JPA 2.1。 在我的应用程序中,我有这些实体(简而言之):
@Entity
public class Festival
{
int Id;
String name;
...
@ManyToOne
@JoinColumn(name = "merchant", referencedColumnName = "Id")
Merchant merchant;
}
@Entity
public class Merchant
{
int Id;
String name;
...
@ManyToOne
@JoinColumn(name = "category", referencedColumnName = "Id")
Category category;
@ManyToOne
@JoinColumn(name = "city", referencedColumnName = "Id")
City city;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "festival")
List<Festival> festivalList;
}
@Entity
public class Category
{
int Id;
String name;
...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "merchant")
List<Merchant> merchantList;
}
@Entity
public class City
{
int Id;
String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "merchant")
List<Merchant> merchantList;
}
因此,(Festival,Merchant)具有双向关系,如(商人,类别)和(商人,城市)
问题是当我删除或更改商家时,仍然在类别merchantList和cities merchantList中有一个未更改的副本!等等..
我该如何管理这些变化?!为什么JPA不会自行更改其他副本?它不会增加错误的副本风险吗?!
答案 0 :(得分:1)
我认为Christian Bauer和Gavin King对“Java Persistence With Hibernate”(第261页)的引用可能对你有用:
与EJB 2.0 CMR相反,Hibernate和JPA关联都是如此 本质上是单向的。
因此,从商家到类别的关联与从类别到商家的关联不同,您需要单独管理它们。
编辑: 我调整了你的初始bean配置,看起来应该: (当然,您将使用适当的主键生成策略。)
@Entity
public class Festival
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int Id;
String name;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "merchant")
Merchant merchant;
}
@Entity
public class Merchant
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int Id;
String name;
@ManyToOne
@JoinColumn(name = "category")
Category category;
@ManyToOne
@JoinColumn(name = "city")
City city;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "merchant")
List<Festival> festivalList;
}
@Entity
public class Category
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int Id;
String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "category")
List<Merchant> merchantList;
}
@Entity
public class City
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int Id;
String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "city")
List<Merchant> merchantList;
}
答案 1 :(得分:1)
确保在调用categories.getMerchantList()之前保持(商家)。
答案 2 :(得分:1)
JPA将您的实体视为常规Java对象,并且不为您维护关系 - 应用程序负责确保在更改一侧时双向关系的双方保持同步。因此,当您从商家取消引用某个城市时,您必须从该城市的商家列表中删除对该商家的引用,然后在必要时进行合并。
否则,通过java对象查看数据将与数据库不同步,直到从数据库刷新对象为止。您可以权衡在需要时保持双方同步或刷新的价值和成本,甚至不映射非拥有方,并确定在逐个实体的基础上更适合您的应用程序。