Java spring mvc模块未更新记录

Java spring mvc模块未更新记录,java,spring,hibernate,spring-mvc,jpa,Java,Spring,Hibernate,Spring Mvc,Jpa,在使用hibernate和jpa的spring mvc应用程序中,我有一个编辑电话号码的模块,当用户输入电话号码和电话号码类型的更改信息时,该模块不会向数据库提交更改。我一直在检查代码,但我看不出问题出在哪里。有人能告诉我下面要做什么改变吗 以下是PhoneNumberController.java的相关方法: @RequestMapping(value = "/patients/{patientId}/phonenumbers/{phonenumberId}/edit", method = R

在使用hibernate和jpa的spring mvc应用程序中,我有一个编辑电话号码的模块,当用户输入电话号码和电话号码类型的更改信息时,该模块不会向数据库提交更改。我一直在检查代码,但我看不出问题出在哪里。有人能告诉我下面要做什么改变吗

以下是PhoneNumberController.java的相关方法:

@RequestMapping(value = "/patients/{patientId}/phonenumbers/{phonenumberId}/edit", method = RequestMethod.GET)
public String initUpdateForm(@PathVariable("phonenumberId") int phonenumberId, Map<String, Object> model) {
    System.out.println("--------------------------------- made it into initUpdateForm() method");
    PhoneNumber phonenumber = this.clinicService.findPhoneNumberById(phonenumberId);
    model.put("phonenumber", phonenumber);
    return "phonenumbers/createOrUpdatePhoneNumberForm";
}

@RequestMapping(value = "/patients/{patientId}/phonenumbers/{phonenumberId}/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public String processUpdateForm(@ModelAttribute("phonenumber") PhoneNumber phonenumber, BindingResult result, SessionStatus status) {
    // we're not using @Valid annotation here because it is easier to define such validation rule in Java
    new PhoneNumberValidator().validate(phonenumber, result);
    if (result.hasErrors()) {return "phonenumbers/createOrUpdatePhoneNumberForm";}
    else {
        this.clinicService.savePhoneNumber(phonenumber);
        status.setComplete();
        return "redirect:/patients?patientID={patientId}&type=phone";
    }
}
下面是createOrUpdatePhoneNumberForm.jsp:

<html lang="en">
<jsp:include page="../fragments/headTag.jsp"/>
<body>
<div class="container">
<jsp:include page="../fragments/bodyHeader.jsp"/>
<c:choose>
    <c:when test="${phonenumber['new']}">
        <c:set var="method" value="post"/>
    </c:when>
    <c:otherwise>
        <c:set var="method" value="put"/>
    </c:otherwise>
</c:choose>

<h2>
    <c:if test="${phonenumber['new']}">New </c:if>
    Phone Number
</h2>

<form:form modelAttribute="phonenumber" method="${method}" class="form-horizontal">
    <div class="control-group" id="patient">
        <label class="control-label">Patient </label>
        <c:out value="${phonenumber.patient.firstName} ${phonenumber.patient.lastName}"/>
    </div>

    <petclinic:inputField label="PhoneNumber" name="number"/>
    <div class="control-group">
        <petclinic:selectField name="type" label="Type" names="${numtypes}" size="5"/>
    </div>
    Preferred number? <form:checkbox path="preferred"/><br>
    OK to leave messages? <form:checkbox path="okmessages"/>
    <td>
    </td>

    <div class="form-actions">
        <c:choose>
            <c:when test="${phonenumber['new']}">
                <button type="submit">Add Phone Number</button>
            </c:when>
            <c:otherwise>
                <button type="submit">Update Phone Number</button> <h3>    Link to delete will go here.</h3>
            </c:otherwise>
        </c:choose>
    </div>
</form:form>
<c:if test="${!phonenumber['new']}">
</c:if>
</div>
</body>
</html>

打印出
getNumber()
getType().getName()
的正确新值。和
“else”
打印出来,但数据库中的数据不会更新。为什么不呢?(请注意,clinicservice调用了
JpaPhoneNumberRepository.java
save()
方法)

问题是您的ClinicServiceImpl>savePhoneNumber方法被注释为@Transactional(readOnly=true)。将其更改为@Transactional

为什么ClinicService.java中的savePhoneNumber方法是@Transactional(readOnly=True)
这就是问题的原因

在保存前,您是否在
过程更新表单
中输入了
系统。输出
,以确保表单中的更改得到应用?您可以在那里删除一半的搜索。那么什么是
clinicService
?Spring JPA存储库?您是否自己实现了任何方法?@chrylis-ClinicService代码可以在下面的链接中看到,尽管我对其进行了一些编辑以处理电话号码之类的内容:请发布您自己的代码。整个问题在于您对宠物诊所应用程序的修改,特别是您的
savePhoneNumber
方法。@chrylis我刚刚从JpaPhoneNumberRepository.java添加了相关方法,该方法在entitymanager中更新数据的代码之前打印出正确更新的值。为了找到问题,您还需要什么?
<html lang="en">
<jsp:include page="../fragments/headTag.jsp"/>
<body>
<div class="container">
<jsp:include page="../fragments/bodyHeader.jsp"/>
<c:choose>
    <c:when test="${phonenumber['new']}">
        <c:set var="method" value="post"/>
    </c:when>
    <c:otherwise>
        <c:set var="method" value="put"/>
    </c:otherwise>
</c:choose>

<h2>
    <c:if test="${phonenumber['new']}">New </c:if>
    Phone Number
</h2>

<form:form modelAttribute="phonenumber" method="${method}" class="form-horizontal">
    <div class="control-group" id="patient">
        <label class="control-label">Patient </label>
        <c:out value="${phonenumber.patient.firstName} ${phonenumber.patient.lastName}"/>
    </div>

    <petclinic:inputField label="PhoneNumber" name="number"/>
    <div class="control-group">
        <petclinic:selectField name="type" label="Type" names="${numtypes}" size="5"/>
    </div>
    Preferred number? <form:checkbox path="preferred"/><br>
    OK to leave messages? <form:checkbox path="okmessages"/>
    <td>
    </td>

    <div class="form-actions">
        <c:choose>
            <c:when test="${phonenumber['new']}">
                <button type="submit">Add Phone Number</button>
            </c:when>
            <c:otherwise>
                <button type="submit">Update Phone Number</button> <h3>    Link to delete will go here.</h3>
            </c:otherwise>
        </c:choose>
    </div>
</form:form>
<c:if test="${!phonenumber['new']}">
</c:if>
</div>
</body>
</html>
@Service
public class ClinicServiceImpl implements ClinicService {

private DocumentRepository documentRepository;
private PatientRepository patientRepository;
private AddressRepository addressRepository;
private PhoneNumberRepository phoneNumberRepository;

@Autowired
public ClinicServiceImpl(DocumentRepository documentRepository, PatientRepository patientRepository, AddressRepository addressRepository, PhoneNumberRepository phoneNumberRepository) {
    this.documentRepository = documentRepository;
    this.patientRepository = patientRepository;
    this.addressRepository = addressRepository;
    this.phoneNumberRepository = phoneNumberRepository;
}

@Override
@Transactional(readOnly = true)
public Collection<DocumentType> findDocumentTypes() throws DataAccessException {return documentRepository.findDocumentTypes();}

@Override
@Transactional(readOnly = true)
public Collection<Gender> findGenders() throws DataAccessException {return patientRepository.findGenders();}

@Override
@Transactional(readOnly = true)
public Collection<Race> findRaces() throws DataAccessException {return patientRepository.findRaces();}

@Override
@Transactional(readOnly = true)
public Patient findPatientById(int id) throws DataAccessException {return patientRepository.findById(id);}

@Override
@Transactional(readOnly = true)
public Collection<Patient> findPatientByLastName(String lastName) throws DataAccessException {return patientRepository.findByLastName(lastName);}

@Override
@Transactional
public void savePatient(Patient patient) throws DataAccessException {
    System.out.println("-------------------------------------- inside clinicservice.savePatient()");
    patientRepository.save(patient);}

@Override
@Transactional(readOnly = true)
public Document findDocumentById(int id) throws DataAccessException {
    System.out.println("--------------- made it into clinicservice.findDocumentById() method");
    return documentRepository.findById(id);}

@Override
@Transactional
public void saveDocument(Document doc) throws DataAccessException {documentRepository.save(doc);}

@Override
@Transactional
public void saveAddress(Address addr) throws DataAccessException {addressRepository.save(addr);}

@Override
@Transactional(readOnly=true)
public Address findAddressById(int id) throws DataAccessException {return addressRepository.findById(id);}

@Override
@Transactional(readOnly = true)
public Collection<State> findStates() throws DataAccessException {return addressRepository.findStates();}

@Override
@Transactional(readOnly = true)
public Collection<PhoneNumberType> findPhoneNumberTypes() throws DataAccessException {return phoneNumberRepository.findPhoneNumberTypes();}

@Override
@Transactional(readOnly = true)
public void savePhoneNumber(PhoneNumber pn) throws DataAccessException {
    System.out.println("++++++++++++++++++++ inside savePhoneNumber(pn) : "+pn.getNumber()+" , "+pn.getType().getName());
    phoneNumberRepository.save(pn);
}

@Override
@Transactional(readOnly=true)
public PhoneNumber findPhoneNumberById(int id) throws DataAccessException {return phoneNumberRepository.findById(id);}
}
@PersistenceContext
private EntityManager em;

@Override
public void save(PhoneNumber phonenumber) {
    System.out.println("------------------------------ inside save(phonenumber) : "+phonenumber.getNumber()+" , "+phonenumber.getType().getName());
    if (phonenumber.getId() == null) {
        System.out.println("phonenumber.getId() == null ");
        this.em.persist(phonenumber);
    }
    else {
        System.out.println("else");
        this.em.merge(phonenumber);}
}