2016-01-06 126 views
1

我有一个子对象的列表映射到我的应用程序中的父对象。现在,当用户从UI中删除任何子条目时,我必须删除子对象和父对象关联,并从数据库中删除子记录。我的代码中的所有内容似乎都很好,但是代码既不会删除父子关联,也不会从数据库中删除子记录。下面是我的代码:休眠 - 无法删除父对象的子对象

服务代码:

List<ServerConfig> existingConfig = serverMasterService.getServerConfigForServer(serverId); 
      Set<ServerConfig> temp = new HashSet<ServerConfig>(); 

      for (ServerConfig sConfig : serverMstr.getServerConfigs()) { 
        for (ServerConfig eConfig : existingConfig){ 
         if(sConfig.getAttributeId() == eConfig.getAttributeId()){ 
          sConfig.setConfigId(eConfig.getConfigId()); 
         }else{ 
          temp.add(sConfig); 
         } 
        } 
        sConfig.setServer(serverMstr); 
      } 
      serverMstr.getServerConfigs().removeAll(temp); 
     } 
    this.serverMasterService.saveServerMasters(serverMstr); 

DAO代码:

public void saveServerMasters(ServerMstr serverMstr) { 
     hibernateTemplate.saveOrUpdate(serverMstr); 
    } 

父HBM文件:

<set name="serverConfigs" inverse="true" cascade="all" lazy="false"> 
     <key> 
      <column name="serverId" not-null="true"/> 
     </key> 
     <one-to-many class="com.serverApp.business.model.ServerConfig"/> 
    </set> 

儿童HBM文件:

<many-to-one name="server" class="com.serverApp.business.model.ServerMstr" 
    cascade="all" lazy="false" foreign-key="FK_SERVERMSTR" > 
     <column name="ServerId" not-null="true"/> 
    </many-to-one> 

即使我删除由下面的代码的所有子记录,子对象没有被清除。

serverMstr.getServerConfigs().removeAll(serverMstr.getServerConfigs()); 
this.serverMasterService.saveServerMasters(serverMstr); 

编辑

父对象类:

package com.serverApp.business.model; 

import java.util.Set; 

import javax.xml.bind.annotation.XmlRootElement; 

import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 
import com.fasterxml.jackson.annotation.JsonProperty; 

@XmlRootElement(name = "ServerMaster") 
@JsonIgnoreProperties({"environmentMstr"}) 
public class ServerMstr  { 

@JsonProperty("ID") 
private Long id; 

@JsonProperty("ServerConfigs") 
private Set<ServerConfig> serverConfigs; 

public Set<ServerConfig> getServerConfigs() { 
    return serverConfigs; 
} 


public void setServerConfigs(Set<ServerConfig> serverConfigs) { 
    this.serverConfigs = serverConfigs; 
} 

public Long getId() { 
    return id; 
} 


public void setId(Long id) { 
    this.id = id; 
} 

@JsonProperty("Name") 
private String name; 

@JsonProperty("Notes") 
private String notes; 

@JsonProperty("Location") 
private String location; 

@JsonProperty("SerialNo") 
private String serialNo; 

@JsonProperty("ServerFunction") 
private String serverFunction; 

@JsonProperty("ServerType") 
private String serverType; 

@JsonProperty("PrimAppl") 
private String primAppl; 

@JsonProperty("Status") 
private String status; 

@JsonProperty("IPAddress") 
private String ipAddr; 

public String getLocation() { 
    return location; 
} 


public void setLocation(String location) { 
    this.location = location; 
} 


public String getSerialNo() { 
    return serialNo; 
} 


public void setSerialNo(String serialNo) { 
    this.serialNo = serialNo; 
} 


public String getServerFunction() { 
    return serverFunction; 
} 


public void setServerFunction(String serverFunction) { 
    this.serverFunction = serverFunction; 
} 


public String getServerType() { 
    return serverType; 
} 


public void setServerType(String serverType) { 
    this.serverType = serverType; 
} 


public String getPrimAppl() { 
    return primAppl; 
} 


public void setPrimAppl(String primAppl) { 
    this.primAppl = primAppl; 
} 


public String getStatus() { 
    return status; 
} 


public void setStatus(String status) { 
    this.status = status; 
} 


public String getIpAddr() { 
    return ipAddr; 
} 


public void setIpAddr(String ipAddr) { 
    this.ipAddr = ipAddr; 
} 


public String getNotes() { 
    return notes; 
} 

public void setNotes(String notes) { 
    this.notes = notes; 
} 

public ServerMstr(){ 
} 

public ServerMstr( String name, String notes){ 
    this.name = name; 
    this.notes=notes; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 


@Override 
public String toString() { 
    return "ServerMstr [id=" + id + ", serverConfigs=" + serverConfigs 
      + ", name=" + name + ", notes=" + notes + ", location=" 
      + location + ", serialNo=" + serialNo + ", serverFunction=" 
      + serverFunction + ", serverType=" + serverType + ", primAppl=" 
      + primAppl + ", status=" + status + ", ipAddr=" + ipAddr + "]"; 
} 

} 

子对象:

package com.serverApp.business.model; 


import javax.xml.bind.annotation.XmlRootElement; 

import com.fasterxml.jackson.annotation.JsonIgnore; 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 
import com.fasterxml.jackson.annotation.JsonProperty; 


@XmlRootElement(name = "ServerConfig") 
@JsonIgnoreProperties({"configId", "server"}) 
public class ServerConfig { 

@JsonIgnore 
private ServerMstr server; 

private Long configId; 



@Override 
public String toString() { 
    return "ServerConfig [server=" + server.getName() + ", configId=" + configId 
      + ", attributeId=" + attributeId + ", value=" + value 
      + ", serverId=" + serverId + "]"; 
} 

@JsonProperty("AttributeId") 
private Long attributeId; 

@JsonProperty("Value") 
private String value; 

@JsonProperty("ServerId") 
private Long serverId; 


public Long getConfigId() { 
    return configId; 
} 

public void setConfigId(Long configId) { 
    this.configId = configId; 
} 

public Long getServerId() { 
    return serverId; 
} 

public void setServerId(Long serverId) { 
    this.serverId = serverId; 
} 

public Long getAttributeId() { 
    return attributeId; 
} 

public void setAttributeId(Long attributeId) { 
    this.attributeId = attributeId; 
} 


public String getValue() { 
    return value; 
} 

public void setValue(String value) { 
    this.value = value; 
} 

public ServerConfig() { 
} 

public ServerConfig(Long serverId, Long attributeId, String value) 
{ 
    this.serverId = serverId; 
    this.attributeId = attributeId; 
    this.value=value; 
} 

public void setServer(ServerMstr server) { 
    this.server = server; 
} 

public ServerMstr getServer() { 
    return server; 
} 

} 

DAO代码:

package com.serverApp.business.dao; 

import java.util.List; 

import org.apache.log4j.Logger; 
import org.hibernate.criterion.DetachedCriteria; 
import org.hibernate.criterion.Restrictions; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 

import com.serverApp.business.model.ServerConfig; 
import com.serverApp.business.model.ServerMstr; 

@Repository ("serverMstrDao") 
public class ServerMstrDaoImpl extends AbstractDAOImpl implements ServerMstrDao{ 

private static final Logger logger = Logger.getLogger(ServerMstrDaoImpl.class); 

/* 
* This Method will be used to retrieve the list of ServerMstr Class Details from the DB 
* (non-Javadoc) 
* @see com.serverApp.business.dao.ServerMstrDao#listServerMstrs() 
*/ 
@Override 
@SuppressWarnings({"unchecked" }) 
public List<ServerMstr> listServerMstrs() { 
    if (logger.isDebugEnabled()) { 
     logger.debug("Inside listServerMstrs() "); 
    } 
    return (List<ServerMstr>)hibernateTemplate.find("from ServerMstr"); 
} 

/* 
* This Method will be used to save new server to database 
* (non-Javadoc) 
* @see com.serverApp.business.dao.ServerMstrDao#saveServerMasters(com.serverApp.business.model.ServerMstr) 
*/ 
@Override 
@Transactional 
    public void saveServerMasters(ServerMstr serverMstr) { 
    if (logger.isDebugEnabled()) { 
     logger.debug("Inside saveServerMasters() "); 
    } 

     System.out.println("DAO Print: "+serverMstr.toString()); 
     hibernateTemplate.saveOrUpdate(serverMstr); 
    } 

/* 
* This Method will be used to retrieve the ServerMstr Class Details from the DB for the given name 
* (non-Javadoc) 
* @see com.serverApp.business.dao.ServerMstrDao#getServerByName() 
*/ 
@SuppressWarnings("unchecked") 
@Override 
public ServerMstr getServerByName(String name) { 
    if (logger.isDebugEnabled()) { 
     logger.debug("fetching server from database with name : " + name); 
    } 
    DetachedCriteria criteria = DetachedCriteria.forClass(ServerMstr.class); 
    criteria.add(Restrictions.eq("name", name)); 
    List<ServerMstr> serverMstr = hibernateTemplate.findByCriteria(criteria); 
    if(serverMstr.size() != 1) 
    { 
     logger.error("Multiple or 0 row returned for selection Server name: " + name); 
     return null; 
    } 
    return (ServerMstr)serverMstr.get(0); 
} 

/* 
* This Method will be used to retrieve the ServerConfig Class List from the DB for the given server id 
* (non-Javadoc) 
* @see com.serverApp.business.dao.ServerMstrDao#getServerConfigForServer() 
*/ 
@SuppressWarnings("unchecked") 
@Override 
public List<ServerConfig> getServerConfigForServer(Long serverId) { 
    if (logger.isDebugEnabled()) { 
     logger.debug("fetching ServerConfig list from database for server with id : " + serverId); 
    } 

    return hibernateTemplate.find("from ServerConfig where serverId = ?",serverId); 
} 
} 

任何帮助/建议是非常感谢

回答

0

你在这种情况下,需要的是删除孤儿。级联类型all确实级联了所有操作,但是对于子对象发生删除操作,您需要对父级进行删除操作,这不是您想要在您的示例中执行的操作。改变你的映射是这样的:

<set name="serverConfigs" inverse="true" cascade="all-delete-orphan" lazy="false"> 
    <key> 
     <column name="serverId" not-null="true"/> 
    </key> 
    <one-to-many class="com.serverApp.business.model.ServerConfig"/> 
</set> 
+2

这是正确的答案。有关更多信息,请参阅此链接中的图表:http://stackoverflow.com/a/19645397/668622。图表的第三行显示要在父级集合被修改时删除子对象,必须使用all-delete-orphan选项。如果您使用注释而不是基于XML的配置,则可以使用例如orphanRemoval = true。 @OneToMany标签。 – KyleM

+0

@KyleM你的链接中的答案提供了一个总结行为的好方法,谢谢 –

+0

我尝试将'cascade'类型与@Pritam Banerjee的解决方案一起更改为'all-delete-orphan',但没有运气。 –

0

你将需要覆盖POJO对象中的equals和haschode方法。如果您不这样做,Hibernate将无法比较子对象,并且它们将继续作为孤儿存在于数据库中。

另一种方法是查找父代的所有子代,然后像下面的代码一样单独删除它们。 :

Iterator<Child> i = form.getDeleteItems().iterator(); 
while(i.hasNext()){ 
Child child = i.next(); 
for (Iterator<Child> it = parent.getChildren().iterator();) { 
    if (child.getId().equals(it.next().getId()) { 
     it.remove(); 
    } 
    } 
} 
+0

我尝试了两种方式。但是hibernate仍然不删除任何子记录或删除关联。 此外,当我重写equals和hashcode方法时,我得到stackOverFlowException。 当我使用“Long”字段手动迭代现有对象列表和新对象列表时,我可以从父对象中删除子对象,但是当保存父对象时,删除的子对象不会从父对象中删除。 –