Java Hibernate级联:取消引用子表中的父PK而不删除子对象
如果父对象以包含3个子对象的列表开始,移除子对象1并调用session.update(父对象),我需要什么样的hibernate映射才能从移除的子表中清除父PK而不完全删除移除的子对象 我还有一个约束,它可以防止在任何子项被指定给父项时删除任何父项,还有一个约束可以防止我意外地级联删除任何子项 我可以通过简单地调用session.update(parent)成功地级联更新子级,但是我在做相反的事情时遇到了麻烦Java Hibernate级联:取消引用子表中的父PK而不删除子对象,java,hibernate,Java,Hibernate,如果父对象以包含3个子对象的列表开始,移除子对象1并调用session.update(父对象),我需要什么样的hibernate映射才能从移除的子表中清除父PK而不完全删除移除的子对象 我还有一个约束,它可以防止在任何子项被指定给父项时删除任何父项,还有一个约束可以防止我意外地级联删除任何子项 我可以通过简单地调用session.update(parent)成功地级联更新子级,但是我在做相反的事情时遇到了麻烦 public class Parent implements Serializable
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private List<Child> children;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy = "parent")
@org.hibernate.annotations.Cascade(
value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children){
this.children = children;
for(Child child : children) {
child.setParent(this);
}
}
//----------------- Would I need something like this? ---------------
//----------------- Or does hibernate have a better way? ---------------
public void setChildren(List<Child> children){
for(Child child : this.children)
if (!children.contains(child)) {
child.setParent(null);
}
}
this.children = children;
for(Child child : children) {
child.setParent(this);
}
}
//----------------------------------------------------------------
}
public class Child implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Parent parent;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
公共类父级实现可序列化{
私有静态最终长serialVersionUID=1L;
私人长id;
私人名单儿童;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@OneToMany(mappedBy=“家长”)
@org.hibernate.annotations.Cascade(
值={org.hibernate.annotations.CascadeType.SAVE_UPDATE})
公共列表getChildren(){
返回儿童;
}
公共子项(列出子项){
这个。孩子=孩子;
用于(儿童:儿童){
child.setParent(this);
}
}
//-----------------我需要这样的东西吗---------------
//-----------------还是冬眠有更好的方法---------------
公共子项(列出子项){
for(Child:this.childs)
如果(!children.contains(child)){
setParent(null);
}
}
这个。孩子=孩子;
用于(儿童:儿童){
child.setParent(this);
}
}
//----------------------------------------------------------------
}
公共类子级实现可序列化{
私有静态最终长serialVersionUID=1L;
私人长id;
私人家长;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@许多酮
公共父getParent(){
返回父母;
}
公共void setParent(父级){
this.parent=parent;
}
}
此解决方案类似,但我不是删除父项,而是从列表中删除子项:
我认为您必须手动将已删除元素的父元素设置为null。hibernate中没有任何东西可以为您做到这一点。通过使用来自BetterBeans绑定项目的。然后可以删除setter,并立即反映更改
public class Parent implements Serializable, ObservableListListener {
private static final long serialVersionUID = 1L;
private Long id;
private List<Child> children;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy = "parent")
@org.hibernate.annotations.Cascade(
value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
public List<Child> getChildren() {
return children;
}
void listElementPropertyChanged(ObservableList list, int index) { // Do Nothing }
void listElementReplaced(ObservableList list, int index, java.lang.Object oldElement) {
listElementAdded(list.get(index));
listElementRemoved(oldElement);
}
void listElementsAdded(ObservableList list, int index, int length) {
for(int i = index; i < index + length; i++) {
((Child)list.get(i)).setParent(this);
}
}
void listElementsRemoved(ObservableList list, int index, java.util.List oldElements) {
for(object element : oldElements) {
((Child)list.get(i)).setParent(null);
}
}
}
公共类父类实现可序列化、可观察的Listener{
私有静态最终长serialVersionUID=1L;
私人长id;
私人名单儿童;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
@OneToMany(mappedBy=“家长”)
@org.hibernate.annotations.Cascade(
值={org.hibernate.annotations.CascadeType.SAVE_UPDATE})
公共列表getChildren(){
返回儿童;
}
void listElementPropertyChanged(ObservableList列表,int索引){//Do Nothing}
void listlementereplaced(observeList列表,int索引,java.lang.Object oldElement){
listElementAdded(list.get(index));
listElementRemoved(oldElement);
}
void listlementsadded(可观察列表、整数索引、整数长度){
for(int i=索引;i<索引+长度;i++){
((子)list.get(i)).setParent(this);
}
}
void listElementsRemoved(ObservableList列表、int索引、java.util.list oldElements){
对于(对象元素:oldElements){
((子)list.get(i)).setParent(null);
}
}
}
如果对子表中的FK parent字段没有not null约束,则可以将parent设置为null并保存子项
我将使用以下方法编写:
Boolean removeChild(Child c) {
Boolean success = getChildren().remove(c);
if(success) c.setParent(null);
return success;
}
我会小心重写setChildren方法,因为hibernate需要普通的getter和setter