我在创建父对象和子对象时遇到问题,并使用JPA和hibernate将它们一次性保存到数据库中。父类看起来像这样:
@Entity
@Table(name = "PUser")
public final class User {
@Id
@Column(name = "ID", unique = true, nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
}
子对象使用复合键,其中一个字段是父级的ID:
@Entity
@Table(name = "PAttribute")
public final class Attribute {
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "domain", column = @Column(name = "domain", nullable = false, length = 128)),
@AttributeOverride(name = "name", column = @Column(name = "name", nullable = false, length = 128)),
@AttributeOverride(name = "userid", column = @Column(name = "userid", nullable = false)) })
private AttributePk pk;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userid", nullable = false, insertable = false, updatable = false)
private User user;
}
复合键类是:
@Embeddable
public class AttributePk implements java.io.Serializable {
private static final long serialVersionUID = -7003721226789641149L;
@Column(nullable = false, length = 128)
private String domain;
@Column(nullable = false, length = 128)
private String name;
@Column(nullable = false)
private long userid;
}
现在,当我创建一个新用户并添加一个附件,然后尝试保存对象图
User user = new User("joe1.bloggs@ft.com", "xyz");
user.setScreenName("joe1bloggs");
user.addAttribute("domain", "name", 212);
target.saveAndFlush(user);
我得到了例外
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`fta_portal_user/PAttribute`, CONSTRAINT `userId` FOREIGN KEY (`userid`) REFERENCES `PUser` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
显然,Attribute子对象没有用户对象集的ID。
我知道我可以执行以下操作,但这似乎很奇怪,我不能只创建一个对象层次结构,而Hibernate可以解决如何相应地设置ID的问题。我怀疑没有办法绕过这个,因为saveAndFlush()返回一个新实例,而不仅仅是更新输入参数版本。
User user = new User("joe1.bloggs@ft.com", "xyz");
user.setScreenName("joe1bloggs");
// target is an JpaRepository intergafe
user = target.saveAndFlush(user);
user.addAttribute("domain", "name", 212);
target.saveAndFlush(user);
任何人都有任何想法,或者只是与它一起生活的情况?
由于
尼克
编辑:您可以通过将@MapsId注释添加到子类来实现此功能(感谢axtavt的回复)。即
@MapsId("userId")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userId", nullable = false, insertable = false, updatable = false)
private User user;
答案 0 :(得分:1)
您是否尝试按如下方式进行映射:
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("userid")
private User user;
据我所知,在这种情况下,userid
的{{1}}字段应自动填充AttributePk
的ID。