2014-10-27 261 views
0

我们正在使用Hibernate作为在Tomcat服务器中运行的提供程序的JPA项目。问题是当我试图更新实体时,它不会发生并导致异常。 HostConfiguration是我想使用类SystemDaoImpl更新的实体。这里的HostConfiguration又将InterfaceConfiguration作为子实体。 HostConfiguration有2个InterfaceConfiguration(s) - 可信和不可信。我的目标是 (a)更新其中一个接口配置,即删除现有的接口配置并替换一个新的接口配置。(b)删除具有所有接口配置的完整主机配置,然后添加一个新配置。我想知道我该怎么做?在通过网络进行多个论坛后,我尝试了各种方式/组合。下面的代码给了我这个例外 -JPA - 无法更新实体

org.hibernate.ObjectDeletedException:删除的对象将是 重新保存通过级联(移除协会删除的对象): [com.cisco.cpm.ipep.system。 InterfaceConfiguration#InterfaceConfiguration.IfConfigPKey [type = TRUSTED,ipAddress =/7.7.20.18]]

感谢任何帮助,谢谢。

//SystemDaoImpl.java 

public class SystemDaoImpl { 

//code omiited 
@Override 

public void setHostConfig(HostConfiguration hostConf) { 

     HostConfiguration hc = em.find(HostConfiguration.class, hostConf.getHostname()); 
     if(hc != null) { 
     InterfaceConfiguration trusted = hc.getTrustedInterface(); 
     InterfaceConfiguration untrusted = hc.getUntrustedInterface(); 

     if(!hostConf.equals(hc) || !trusted.equals(hostConf.getTrustedInterface()) || !untrusted.equals(hostConf.getUntrustedInterface())) { 
     log.info("removing the existing hostconf"); 
     em.remove(hc); 
     InterfaceConfiguration.IfConfigPKey tpkey = new InterfaceConfiguration.IfConfigPKey();     
     tpkey.setType(Type.TRUSTED); 
     tpkey.setIpAddress(trusted.getIpAddress()); 
     InterfaceConfiguration trusted1 = em.find(InterfaceConfiguration.class, tpkey); 
     if(trusted1 != null) { 
     em.remove(trusted1); 
     } 
     InterfaceConfiguration.IfConfigPKey upkey = new InterfaceConfiguration.IfConfigPKey();     
     tpkey.setType(Type.UNTRUSTED); 
     tpkey.setIpAddress(untrusted.getIpAddress()); 
     InterfaceConfiguration untrusted1 = em.find(InterfaceConfiguration.class, upkey); 
     if(untrusted1 != null) { 
     em.remove(untrusted1); 
     } 
     log.info("now adding the new hostconf: " + hostConf); 
     em.merge(hostConf); 
     } else { 
     log.info("hostConf and existing hostConf are equal"); 
     } 
     } 

//some code removed ... 
     } 

HostConfiguration.java

@Entity 

@Table(name = "host_configurations") 

@XmlRootElement(name = "host_configuration") 

@XmlAccessorType(XmlAccessType.FIELD) 

public class HostConfiguration implements Cloneable { 
public enum HostType { 

    PRIMARY, SECONDARY, SERVICE 
    } 



@Id 

@XmlElement 

private String hostname; 

@XmlElement 

private String peerHostname; 

@Enumerated 

@XmlElement 

private HostType type = HostType.PRIMARY; 
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 

@JoinColumns({ 

     @JoinColumn(name = "trusted_interface_type", referencedColumnName = "type", nullable = false), 
     @JoinColumn(name = "trusted_interface_ip_address", referencedColumnName = "ip_address", nullable = false) }) 

@XmlElement(name = "trusted_interface") 

private InterfaceConfiguration trustedInterface; 

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 

@JoinColumns({ 

     @JoinColumn(name = "untrusted_interface_type", referencedColumnName = "type", nullable = false), 

     @JoinColumn(name = "untrusted_interface_ip_address", referencedColumnName = "ip_address", nullable = false) }) 

@XmlElement(name = "untrusted_interface") 

private InterfaceConfiguration untrustedInterface; 

//code removed 

} 

InterfaceConfiguration.java

@Entity 

@Table(name = "interface_configurations") 

@IdClass(InterfaceConfiguration.IfConfigPKey.class) 

@XmlAccessorType(XmlAccessType.FIELD) 

public class InterfaceConfiguration implements Cloneable { 
public enum Type { 
TRUSTED, UNTRUSTED 
} 

@Id 

@Enumerated 

@XmlElement 

private Type type; 

@Id 

@Column(name = "ip_address") 

@XmlElement(name = "ip_address") 

@XmlJavaTypeAdapter(value = InetAddressXmlAdapter.class) 

private InetAddress ipAddress; 

@XmlElement 

private Subnet netmask; 

@Column(name = "vlan_native") 

@XmlElement(name = "vlan_native") 

private boolean vlanNative; 

@XmlElement 

@XmlJavaTypeAdapter(value = InetAddressXmlAdapter.class) 

private InetAddress gateway; 

@Column(name = "vlan_id") 

@XmlElement(name = "vlan_id") 

private int vlanId; 

//code removed 

} 

回答

0

问题IST该代码有一个/级联对孩子们的声明和B /试图直接操作孩子而不更新父母的参考资料。带有cascade选项的使用案例删除的HostConfiguration包括两个InterfaceConfiguration的是这样:

em.remove(hc); 

和修改在诸如HostConfiguration的InterfaceConfigurations:

hc.setTrustedInterface(...); 
hc.setUntrustedInterface(...); 
entityManager.merge(hc); 

如果你要管理的孩子和父实体明确地删除Cascade注释。

+0

随着级联,我试图修改孩子使用上述方法,即 hc.setTrustedInterface(...); hc.setUntrustedInterface(...); entityManager.merge(hc); 但是,这不帮助我。 – sburnwal 2014-10-28 10:47:28

+0

你能更新你的源代码吗?在这种情况下,它不应该包含em.remove(trusted1);了,对吧?你现在收到什么错误? – Michal 2014-10-29 17:09:26