2011-04-28 149 views
4

我在從Many to Parent關係映射ManyToOne時遇到問題。 OneToMany收藏品可以很好地填充。但是,與單個實體相反,並不是。父/子關係的Hibernate註釋映射?

我有一個Server實例表,它是不可變的。

當我創建一個服務器列表時,它會填充服務器爲其分配的請求集合,而不會出現任何問題。

當我添加一個新的請求,並從下拉菜單saveOrUpdate(甚至嘗試加載並獲取)中選擇服務器首選項時,它不會填充請求實例中的服務器屬性。

Server.java

public class Server { 

    private int serverId; 
    private List<Request> requests; 
    ... 
    @OneToMany(mappedBy="server", fetch=FetchType.LAZY) 
    public List<Request> getRequests() { 
     return requests; 
    } 
} 

Request.java

public class Request { 

    private int requestId; 
    private int server_serverId; // foreign key to Server.serverId 
    private Server server; 
    ... 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="server_serverId", nullable=false, updatable=false, insertable=false} 
    @ForeignKey(name="server_serverId", inverseName="serverId") // Don't think this really does anything 
    public Server getServer() { 
     return server; 
    } 
} 

add.jsp(ADD請求形式)

... 

<form:select id="preferred-server" path="server.serverId"> 
    <c:forEach items="${servers}" var="server"> 
     <form:option value="${server.serverId}">${server.serverName}</form:option> 
    </c:forEach> 
</form:select> 

... 

AddRequestController.java

public class AddRequestController extends SimpleFormController { 
    ... 
    @Override 
    protected ModelAndView onSubmit(Object command) throws Exception { 

    Request request = (Request)command; 

    try { 
     logger.info("BEFORE SAVE, request.server = " + request.getServer()); 
    } catch (NullPointerException npe) { 
     logger.error("onSubmit() caught NPE: " + npe); 
    } 

    // Would rather not do these next two lines. Would prefer to saveOrUpdate 
    // Request, and have it populate server property via server_serverId foreign key. 
    //Server server = serverDao.loadByServerId(request.getServer_serverId()); 
    //request.setServer(server); 
    //Added this instead, which calls getHibernateTemplate().refresh(server, LockMode.READ) 
    serverDao.refreshServer(request.getServer()); 

    requestDao.addRequest(request); // calls getHibernateTemplate.saveOrUpdate(request) 

    try { 
     logger.info("AFTER SAVE, request.server = " + request.getServer()); 
    } catch (NullPointerException npe) { 
     logger.error("onSubmit() caught NPE: " + npe); 
    }   

    return new ModelAndView(getSuccessView(), "request", request); 
    } 
} 

我已經嘗試過幾乎所有可以在網上找到的註解映射的組合,這是用於獲取請求集合的設置。

當然,我可以從SimpleFormController獲取我的Request命令對象,根據用戶選擇的內容加載服務器對象,並以此方式堅持 - 但這不是關係映射點,現在是它?

有什麼建議嗎?讓我知道你是否需要其他代碼。

使用:Spring 2.5中的Hibernate 3.2.5中,Sybase數據庫

回答

1

的問題是,Request是擁有方,所以你需要將服務器添加到請求,即調用setServer()server字段是數據庫中相應列的負責人。

將請求添加到列表中是不夠的,因爲那只是逆映射。如果你在請求中設置服務器,然後從數據庫重新加載服務器,請求應該自動添加到列表中(儘管通常不會這樣做,但也可以手動將服務器添加到列表中)。

因此請求應該是這樣的:

public class Request { 

private int requestId; 
//I don't see any need for this 
//private int server_serverId; // foreign key to Server.serverId 
private Server server; 
... 
@ManyToOne (fetch=FetchType.LAZY) //employ lazy loading, you can put that on @OneToMany too 
@JoinColumn(name="server_serverId", nullable=false } 
public Server getServer() { 
    return server; 
} 
} 
+0

我相信我試過設置,但我會再次。問題是,我希望能夠選擇Request(s)並通過Hibernate映射自動填充服務器屬性。因此,server_serverId外鍵標識對於將Request映射到服務器是必要的(因爲服務器對象純粹用於ORM,而不是數據庫中的列)。 – 2011-04-28 20:46:13

+0

我不確定我是否理解你的觀點,但僅僅使用服務器應該足夠了,無論如何,sinc服務器ID的外鍵應映射到請求表中的列'server_serverId'。請注意,您可能也想使用延遲加載,我會相應地更新答案。 – Thomas 2011-04-28 20:51:59

+0

我用我的SimpleFormController實現更新了我的問題。 – 2011-04-28 20:53:14