【问题标题】:Spring MVC with Hibernate - OneToMany mapping in formSpring MVC with Hibernate - 表单中的 OneToMany 映射
【发布时间】:2012-03-29 16:49:16
【问题描述】:

我有 Car 和 Rental 模型连接到 OneToMany 关系:

@Entity
public class Rental {

private Long id;
private Car car;
private User user;

@Id
@GeneratedValue
@Column(name = "RENTAL_ID")
public Long getId() {
    return id;
}

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

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "CAR_ID")
public Car getCar() {
    return car;
}

public void setCar(Car car) {
    this.car = car;
}

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID")
public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}
}





@Entity
public class Car {

private Long id;
private String name;
private String description;

@Id
@GeneratedValue
@Column(name = "CAR_ID")
public Long getId() {
    return id;
}

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

我想在创建租赁时设置汽车:

<form:form method="POST" commandName="rental">
<form:errors path="*" cssClass="errorblock" element="div" />
<table cellspacing="10">
    <tr>
        <td>Car</td>
        <td>
        <form:select path="car" multiple="false" items="${cars}" itemLabel="name" itemValue="id"/></td>
    </tr>
    <tr>
        <td colspan="2"><input type="submit" value="Create"></td>
    </tr>
</table>

Form:select 标记显示正确可用的汽车,但在提交后,Rental 的 Car 实例变量为空。

@Controller
@RequestMapping("/make-rental.htm")
public class MakeRentalController {

private CarDAO carDAO;
private UserDAO userDAO;
private RentalDAO rentalDAO;

@Autowired
public void setCarDAO(CarDAO carDAO) {
    this.carDAO = carDAO;
}

@Autowired
public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
}

@Autowired
public void setRentalDAO(RentalDAO rentalDAO) {
    this.rentalDAO = rentalDAO;
}

@RequestMapping(method = RequestMethod.GET)
public String initForm(ModelMap mapModel) {
    Rental rental = new Rental();

    // command object
    mapModel.addAttribute("cars", carDAO.getAll());
    mapModel.addAttribute("rental", rental);

    // return form view
    return "makeRentalFormView";
}

@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("rental") Rental rental,
        BindingResult result, SessionStatus status, HttpSession session) {
    Object userId = session.getAttribute("userId");
    if (userId != null) {
        rental.setUser(userDAO.getById((Long) userId));
        rentalDAO.save(rental);

        // clear the command object from the session
        status.setComplete();
    }

    // form success
    return "redirect:/index.htm";
}
}

怎么了?

【问题讨论】:

    标签: forms spring hibernate many-to-one


    【解决方案1】:

    你应该在你的应用程序中实现一个服务层

    例如:

    public interface RentalService {
        void addRental(Rental rental, Long userId, Long carId);
    }
    

    实施:

    @Service
    @Transactional
    class DefaultRentalService implement RentalService {
    
        @Autowired
        private CarDAO carDAO;
        @Autowired
        private UserDAO userDAO;
        @Autowired
        private RentalDAO rentalDAO;
    
        @Override
        void addRental(Rental rental, Long userId, Long carId) {
            User user = userDAO.getById(userId);
            Car car = carDAO.getById(carId);
            rental.setUser(user);
            rental.setCar(car);
            rentalDao.save(rental);
        }
    }
    

    HTML:

    <form:form method="POST" commandName="rental">
    <form:errors path="*" cssClass="errorblock" element="div" />
    <table cellspacing="10">
        <tr>
            <td>Car</td>
            <td>
            <select name="carId" >
                <c:forEach items="${cars}" var="car">
                   <option value="${car.id}">${car.name}
                </c:forEach>
            </select>
         </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Create"></td>
        </tr>
    </table>
    

    控制器:

    @AutoWired
    private RentalService rentalService;
    
    // ..
    // ..
    
    @RequestMapping(method = RequestMethod.POST)
    public String processSubmit(@ModelAttribute("rental") Rental rental, @RequestParam Long carId,
            BindingResult result, SessionStatus status, HttpSession session) {
        Object userId = session.getAttribute("userId");
        if (userId != null) {
            rentalService.add(rental, (Long)userId, carId);
            status.setComplete();
        }
    
        // form success
        return "redirect:/index.htm";
    }
    

    【讨论】:

    • 我认为它可以由带有 JSTL 的视图层提供服务。这是一种解决方法,但它有效
    • 你的答案是有效的,但从长远来看,它最终会淡化ORM在应用程序开发过程中的用途。但是,我喜欢您将userIdcarId 推送到服务层的想法。
    【解决方案2】:

    【讨论】:

    • 这实际上是正确的方法。也可以编写转换器的层次结构。可惜OP选择了另一个答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2012-02-08
    • 2019-02-24
    相关资源
    最近更新 更多