2011-04-28 147 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