带有Hibernate的Spring MVC - 表单中的OneToMany映射

bon*_*ade 7 forms spring hibernate many-to-one

我有汽车和租赁模型连接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;
}
...
}
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)

表单:选择标签显示正确可用的汽车,但提交后汽车的实例变量租赁为空.

@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";
}
}
Run Code Online (Sandbox Code Playgroud)

怎么了?

Pau*_*Wee 8

您应该在您的应用程序中实现服务层

例如:

public interface RentalService {
    void addRental(Rental rental, Long userId, Long carId);
}
Run Code Online (Sandbox Code Playgroud)

执行:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

控制器:

@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";
}
Run Code Online (Sandbox Code Playgroud)