كيفية حفظ خصائص محددة لسمة نموذج كيان JPA من صفحة JSP

StackOverflow https://stackoverflow.com/questions/3610079

سؤال

نحن نستخدم Beans JPA Entity كطراز الخاص بنا لوحدة التحكم MVC Spring على صفحة JSP. إحدى صفحات JSP الخاصة بنا هي وجهة نظر جزئية لهذا الكيان والتي لا تظهر جميع الخصائص. كلما حاولنا تحديث كياننا باستخدام طبقة الخدمة من وحدة التحكم فقط ، يتم استمرار الخصائص المستخدمة في نموذج JSP ويتم إلغاء جميع الآخرين. ما هي الطريقة الصحيحة للتعامل مع هذا الموقف؟ لا نريد أن نضطر إلى تحديد الحقول المخفية على النموذج.

لذلك في هذه الحالة عندما يقوم وحدة التحكم باستدعاء Service.Update (العميل) ، سيكون حقل الاسم لاغويًا لأنه غير موجود في form.jsp.

form.jsp

<form:form modelAttribute="client" method="get" action="${action}">
<table width="100%">
    <tr>
        <td>
            <table>
                <tr>
                    <td valign="top"><spring:message code="label.tradeOrderManagementSystem"/>:</td>
                    <td>
                        <form:select path="tradeOrderManagementSystems" >
                            <form:options items="${tradeOrderManagementSystemList}" itemValue="id" itemLabel="name" />
                        </form:select>
                        <a href="<spring:url value="/tradeOrderManagementSystem/add"/>" class="addAndReturn"><span><spring:message code="add"/></span></a>
                    </td>
                    <td>
                        <form:errors path="tradeOrderManagementSystems" cssClass="errors" />
                    </td>
                </tr>
                <tr><td></td><td>&nbsp;</td></tr>
            </table>
        </td>
    </tr>
</table>
<input type="hidden" name="submitted" value="true">

مراقب

@RequestMapping("/{id}/edit")
public ModelAndView edit(HttpServletRequest request,
        HttpServletResponse response,
        @ModelAttribute("client") Client client,
        BindingResult result,
        @PathVariable("id") int id,
        Model model) {
    ControllerContext ctx = new ControllerContext(request, response);
    init(ctx);

    setAdvancedSearchAvailable(ctx, true);
    buildShowAndEditVerticalMenu(ctx, id, false);

    if (id == 0) {
        result.addError(new ObjectError("client", getMessage("error.idNeeded")));
        return getModelAndView(ctx, "itEfficiencies/form");
    } else {
        if (!isSubmission(ctx)) {
            client = clientService.find(id);
            model.addAttribute("client", client);
            fillClientForm(model);
            return getModelAndView(ctx, "itEfficiencies/form");
        } else {
            //clientValidator.validate(client, result);
            if (result.hasErrors()) {
                fillClientForm(model);
                return getModelAndView(ctx, "itEfficiencies/form");
            } else {
                try {
                    //checkClientProperties(client);
                    client.setId(id);
                    client = clientService.update(client);  //method updates only form fields and nulls out all others
                } catch (Exception e) {
                    e.printStackTrace();
                    result.addError(new ObjectError("client", getMessage("error.save")));
                    fillClientForm(model);
                    return getModelAndView(ctx, "itEfficiencies/form");
                }
                return getModelAndView(ctx, "/staffingByClient/" + client.getId() + "/show", true);
            }
        }
    }
}    

client.java

@Entity
public class Client extends AbstractEntity<Integer> {

private static final long serialVersionUID = 1L;

public static final String FIND_BY_NAME = "Client.FIND_BY_NAME";

public static final String COUNT_BY_NAME = "Client.COUNT_BY_NAME";

@Basic(optional = false)
@Column(nullable = false, length = 125)
private String name;

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(inverseJoinColumns = {
    @JoinColumn(name = "trade_order_management_system_id")}, uniqueConstraints =
@UniqueConstraint(name = "UK_client_trade_order_mgmt_client_id_trade_order_mgmt_id",
columnNames = {"client_id", "trade_order_management_system_id"}))
@ForeignKey(name = "FK_client_trade_order_management_systems_client_id",
inverseName = "FK_client_trade_order_mgmt_sys_trade_order_management_system_id")
private List<TradeOrderManagementSystem> tradeOrderManagementSystems;

public Client() {
}

public Client(Integer id) {
    this.id = id;
}

public Client(Integer id, String name) {
    this.id = id;
    this.name = name;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}   

public List<TradeOrderManagementSystem> getTradeOrderManagementSystems() {
    return tradeOrderManagementSystems;
}

public void setTradeOrderManagementSystems(List<TradeOrderManagementSystem> tradeOrderManagementSystems) {
    this.tradeOrderManagementSystems = tradeOrderManagementSystems;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Client)) {
        return false;
    }
    Client other = (Client) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

}

طرق الخدمة

public abstract class CrudService<T, ID extends Serializable> extends DAOImpl<T, ID> {

/**
 * Updates an entity from an existing entity.
 *
 * @since 0.0.1
 * 
 * @param entity
 * @return the managed instance of the updated entity
 */
@Override
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
public T update(T entity, ID id) {
    return super.update(assignDefaultValues(entity), id);
}

}

public abstract class DAOImpl<T, ID extends Serializable> implements DAO<T, ID> {

private Class<T> persistentClass;

@PersistenceContext(unitName = "krfsPersistenceUnit")
protected EntityManager entityManager;

/**
 * Instantiates an instance of this class and sets the <code>persistentClass</code>
 * based on the identifier type
 *
 * @since 0.0.1
 */
public DAOImpl() {
    this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

/**
 * @since 0.0.1
 * 
 * @return the type to be persisted
 */
@Override
public Class<T> getPersistentClass() {
    return persistentClass;
}

/**
 * Updates an entity from an existing entity.
 *
 * @since 0.0.1
 * 
 * @param entity
 * @param id the identifier of the entity
 * 
 * @return the managed instance of the updated entity
 */
@Override
public T update(T entity, ID id) {
    //Find a managed instance of the entity first and copy the properties
    //to the passed in entity before merging.  This ensures that entityManager
    //will not create a new entity with merge.
    Object ref = this.entityManager.getReference(persistentClass, id);
    if (ref != null) {
        BeanUtils.copyProperties(entity, ref);
    }
    return (T) this.entityManager.merge(ref);
}

}

هل كانت مفيدة؟

المحلول

أنت لا تعطي حقًا تفاصيل كافية (على وجه التحديد ، الرمز الذي يوضح كيفية حفظ القيم من النموذج سيساعد) ولكن أظن أنك تقوم بدمج كيان منفصل مع null صفات. وبسبب الطريق merge يعمل (يقوم بنسخ حالة الكيان المنفصل على كيان مع نفس معرف قاعدة البيانات المحملة في سياق الثبات) ، تحصل على خميرة.

تحتاج إلى إما:

  • إبقاء الكيان المنفصل بطريقة أو بأخرى ، ونسخ نموذج القيم النموذج فيه ، ثم merge انها ~ أو ~
  • قم بتنفيذ "دمج يدوي" أي تحميل الكيان لتحديث باستخدام معرفه ، ونسخ القيم الجديدة من النموذج واترك JPA تحديثه.

إذا فاتني هذه النقطة ، فيرجى تقديم المزيد من التفاصيل لفهم المشكلة.

تحديث: أنا لا أفهم الكود الخاص بك. أنت تقوم بنسخ العقارات من عند ref ل entity (العميل المنفصل قادم من العرض) ، ثم الاندماج ref... لا ، أنا لا أفهم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top