2016-01-06 130 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」字段手動迭代現有對象列表和新對象列表時,我可以從父對象中刪除子對象,但是當保存父對象時,刪除的子對象不會從父對象中刪除。 –