【发布时间】:2018-03-19 15:04:19
【问题描述】:
在自动完成中,我得到了预期的产品名称。
我想根据所选产品进行一些计算。但在 doCalculation 函数中,我得到的是id 而不是“价格”。所以计算没有按预期工作。
假设如果我更改 String idExpression = "#{price}"; 然后计算按预期工作但订单未保存。由于出现如下错误
Failed to convert property value of type [java.lang.String] to required type [com.myapp.domain.Product] for property product; nested exception is
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.persistence.OneToOne
@io.springlets.format.EntityFormat com.myapp.domain.Product] for value 2500; nested exception is java.lang.IllegalStateException: Parsers are not allowed to return null: io.springlets.format.EntityParser@2201ba1c
所以我想在保存功能不应该被破坏的同时得到计算价格。现在第一个或第二个对我有用。
ProductsCollectionThymeleafController.java
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE, name = "select2", value = "/s2")
@ResponseBody
public ResponseEntity<Select2DataSupport<Product>> select2(GlobalSearch search, Pageable pageable,
Locale locale) {
Page<Product> products = getProductService().findAll(search, pageable);
String idExpression = "#{id}";
Select2DataSupport<Product> select2Data =
new Select2DataWithConversion<Product>(products, idExpression, getConversionService());
return ResponseEntity.ok(select2Data);
}
OrderCollectionThymeleafController.java
@PostMapping(name = "create")
public ModelAndView create(@Valid @ModelAttribute Order order, BindingResult result,
Model model) {
if (result.hasErrors()) {
populateForm(model);
return new ModelAndView("/order/create");
}
Order newOrder = getOrderService().save(order);
UriComponents showURI = getItemLink().to(OrderItemThymeleafLinkFactory.SHOW)
.with("order", newOrder.getId()).toUri();
return new ModelAndView("redirect:" + showURI.toUriString());
}
orderview.html
<form class="form-horizontal validate" method="POST" data-th-object="${order}" data-th-action="@{${collectionLink.to('create').with('order', order.id)}}">
<fieldset id="containerFields">
<div class="form-group has-error has-feedback" data-z="3c00987d" id="servicio-product-field" data-th-classappend="${#fields.hasErrors('product')}? 'has-error has-feedback'" data-th-class="form-group" data-th-with="collectionLink=${@linkBuilder.of('ProductsCollectionThymeleafController')}">
<label for="product" class="col-md-3 control-label" data-th-text="#{label_servicio_product}">Product</label>
<div class="col-md-6">
<!-- Select2 -->
<select data-th-field="*{product}" onChange="doCalculation()" class="form-control dropdown-select-ajax" data-allow-clear="true" data-data-ajax--url="${collectionLink.to('select2')}" data-ajax--cache="true" data-ajax--delay="250" data-ajax--data-type="json" data-data-placeholder="#{info_select_an_option}">
<option data-th-unless="*{product} == null" data-th-value="*{product.id}" data-th-text="*{{product}}" selected="selected">Product</option>
</select>
<span data-th-classappend="${#fields.hasErrors('product')}? 'glyphicon glyphicon-remove form-control-feedback'" class="glyphicon glyphicon-remove form-control-feedback" data-th-if="${#fields.hasErrors('product')}" aria-hidden="true"></span>
<span id="product-error" class="help-block" data-th-if="${#fields.hasErrors('product')}" data-th-errors="*{product}">Error message.</span>
</div>
</div>
<script>
function doCalculation() {
var price = document.getElementById("product").value;
alert("price: " + price);
// Do some calculation
}
doCalculation();
</script>
</fieldset>
</form>
Product.java
@RooJavaBean
@RooToString
@RooJpaEntity
@RooEquals(isJpaEntity = true)
@Entity
@EntityFormat
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String productName;
@Min(1L)
@NumberFormat
private Integer price;
@OneToOne(fetch = FetchType.LAZY)
@EntityFormat
private Order order;
public static final String ITERABLE_TO_ADD_CANT_BE_NULL_MESSAGE = "The given Iterable of items to add can't be null!";
public static final String ITERABLE_TO_REMOVE_CANT_BE_NULL_MESSAGE = "The given Iterable of items to add can't be null!";
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getPrice() {
return this.price;
}
public void setPrice(Integer price) {
this.price = price;
}
public String getProductName() {
return this.productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Order getOrder() {
return this.order;
}
public void setOrder(Order order) {
this.order= order;
}
}
Order.java
@RooJavaBean
@RooToString
@RooJpaEntity
@RooEquals(isJpaEntity = true)
@Entity
@EntityFormat
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Version
private Integer version;
@OneToOne(cascade = { javax.persistence.CascadeType.MERGE,
javax.persistence.CascadeType.PERSIST }, fetch = FetchType.LAZY, mappedBy = "order")
@RooJpaRelation(type = JpaRelationType.AGGREGATION)
@EntityFormat
private Product product;
public static final String ITERABLE_TO_ADD_CANT_BE_NULL_MESSAGE = "The given Iterable of items to add can't be null!";
public static final String ITERABLE_TO_REMOVE_CANT_BE_NULL_MESSAGE = "The given Iterable of items to add can't be null!";
/**
* This `equals` implementation is specific for JPA entities and uses the
* entity identifier for it, following the article in
* https://vladmihalcea.com/2016/06/06/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
*
* @param obj
* @return Boolean
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
// instanceof is false if the instance is null
if (!(obj instanceof Order)) {
return false;
}
return getId() != null && Objects.equals(getId(), ((Order) obj).getId());
}
/**
* This `hashCode` implementation is specific for JPA entities and uses a
* fixed `int` value to be able to identify the entity in collections after
* a new id is assigned to the entity, following the article in
* https://vladmihalcea.com/2016/06/06/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/
*
* @return Integer
*/
public int hashCode() {
return 31;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getVersion() {
return this.version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
public void addToProduct(Product product) {
if (product == null) {
removeFromProduct();
} else {
this.product = product;
product.setOrder(this);
}
}
public void removeFromProduct() {
if (this.product != null) {
product.setOrder(null);
}
this.product = null;
}
}
【问题讨论】:
标签: spring spring-boot thymeleaf jquery-select2 spring-roo