!
这让我发疯了几天,希望有人能帮助我。
情况:
我有一个包含三个表的简单数据模型:
产品(sa_s_prod)
组件(sa_s_comp)
CompProd(sa_l_compprod-这是“产品和组件”的联接表)
联接表(CompProd)具有其他列。
我的(剥离的)实体如下:
@Entity
@Table(name = "sa_s_comp")
public class SComp implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int compId;
@Column(unique = true, nullable = false, length = 50)
private String compName;
@Column(length = 50)
private String compDesc;
@Column(nullable = false)
private Boolean compIsOnAvailability;
@Min(value = 0)
@Column(nullable = false)
private int compIndex;
@Column(nullable = false)
private Lkzs lkz;
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date cdate;
@Column(nullable = false)
private String cuser;
@NotNull
@OneToOne(optional = false)
@JoinColumn(name = "compgroupId", nullable = false)
private SCompGroup group;
@OneToMany(mappedBy = "component", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<LCompProd> products;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "transId", unique = true, nullable = true)
private STrans translation;
...
/**
* Adds the given product to the list of assigned products for this
* component.
*
* @param prod
* the product to be assigned
* @return the component
*/
public void addProduct(SProd prod) {
if (this.products == null)
this.products = new ArrayList<LCompProd>();
LCompProd compprod = new LCompProd(this, prod);
this.products.add(compprod);
compprod.setComponent(this);
}
....
@Entity
@Table(name = "sa_s_prod")
public class SProd implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int prodId;
@NotNull
private Product.Type prodType;
@NotNull
private String prodName;
private String prodDesc;
private BigDecimal prodQuantityDef;
private Globals.Units prodUnitDef;
private Lkzs lkz;
@Temporal(TemporalType.TIMESTAMP)
private Date cdate;
private String cuser;
@OneToOne(optional = false)
@JoinColumn(name = "subcatId", nullable = false)
private SSubCat subcat;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "transId", unique = true)
private STrans translation;
@OneToMany(mappedBy = "product", fetch = FetchType.EAGER)
private List<LCompProd> components;
....
@Entity
@IdClass(LCompProdId.class)
@Table(name = "sa_l_compprod")
public class LCompProd implements Serializable {
@Id
private int compId;
@Id
private int prodId;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "compId", insertable = false, updatable = false)
private SComp component;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "prodId", insertable = false, updatable = false)
private SProd product;
@NotNull
private Lkzs lkz;
@Temporal(TemporalType.TIMESTAMP)
private Date cdate;
private String cuser;
....
public class LCompProdId implements Serializable {
private int compId;
private int prodId;
....
通过此代码,我可以毫无问题地检索组件和相关产品。但是我不能坚持到联接表(CompProd)。即使没有级联进行两次手动操作,仍然存在。
问题是外键约束失败,因为在持久化期间未在“联接数据对象”中设置组件的主键(compId)。
手动设置主键/外键也许是“正常”的行为,但是我不敢相信休眠无法处理这种简单的事情? (希望我是对的;-)
我阅读了许多文章和博客,尝试了不同的方法,但是仍然无法使它起作用(应该以某种方式实现)。
任何帮助表示赞赏。谢谢。
PS:我正在使用JPA2(休眠)。
最佳答案
看来您在SComp和SProd对象创建中获得了compId和prodId值。
如何将生成的ID传播到LCompProd实体?您确定从中获取值的对象是托管实体吗?
例如,如果使用merge调用创建对象,则该参数不会成为托管实体。因此,您不应直接获取生成的ID。您可以通过方法调用的结果获得它。