我遇到了这个奇怪的问题,希望有人可以帮助我。 也许我做错了什么或忽略了什么?
每当我选择所有n种材料时,我选择的模型会被列出n次。 反之亦然,当我选择所有n个模型时,材料会被列出n次。
例如:Material1(已选中) 材料2(选中) 材料3(选中)
Model1(已选中) MODEL2 Model3
结果:
Material1 材料2 材料3
型号1 型号1 型号1
我使用的是Spring 4.0.3,Spring Data JPA 1.4.3,Hibernate 4.3.1,MySQL 5.1.28,Thymeleaf 2.1.2 发布的DTO是正确的,仅包含所选材料和模型。 数据库中的数据也是正确的!
@Getter
@ToString
@Entity
@Table(name = "SKUS")
public class Sku extends BaseEntityAudit {
/**
*
*/
private static final long serialVersionUID = 1L;
@Column(name = "CODE", nullable = false)
protected String code;
@Column(name = "NAME", nullable = false)
protected String name;
@Column(name = "RETAIL_PRICE", nullable = true)
protected BigDecimal retailPrice;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinTable(name = "SKU_MODELS",
joinColumns = {@JoinColumn(name = "SKU_ID", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "MODEL_ID", referencedColumnName = "ID")})
protected List<SkuModel> availableModels;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinTable(name = "SKU_MATERIALS",
joinColumns = {@JoinColumn(name = "SKU_ID", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "MATERIAL_ID", referencedColumnName = "ID")})
protected List<Material> availableMaterials;
public static Builder getBuilder(String code, String name) {
return new Builder(code, name);
}
public void update(String code, String name) {
this.code = code;
this.name = name;
}
public void updatePrice(BigDecimal retailPrice) {
this.retailPrice = retailPrice;
}
public void updateMaterials(List<Material> materials) {
if (!materials.equals(availableMaterials)) {
this.availableMaterials.clear();
this.availableMaterials = materials;
}
}
public void updateModels(List<SkuModel> models) {
if (!models.equals(availableModels)) {
this.availableModels.clear();
this.availableModels = models;
}
}
public static class Builder {
private Sku built;
public Builder(String code, String name) {
built = new Sku();
built.code = code;
built.name = name;
}
public Builder retailPrice(BigDecimal retailPrice) {
built.retailPrice = retailPrice;
return this;
}
public Builder models(List<SkuModel> models) {
built.availableModels = models;
return this;
}
public Builder materials(List<Material> materials) {
built.availableMaterials = materials;
return this;
}
public Sku build() {
return built;
}
}
}
public interface SkuRepository extends JpaRepository<Sku, Long> {}
// SkuService
@Transactional(readOnly = true, rollbackFor = {NotFoundException.class})
@Override
public Sku findById(Long id) throws NotFoundException {
LOGGER.debug("Finding a sku entry with id: {}", id);
Sku found = skuRepository.findOne(id);
LOGGER.debug("Found sku entry: {}", found);
if (found == null) {
throw new NotFoundException("No sku found with id: " + id);
}
return found;
}
@Transactional(rollbackFor = {NotFoundException.class})
@Override
public Sku update(SkuDTO updated) throws NotFoundException {
LOGGER.debug("Updating sku with request information: {}", updated);
Sku model = findById(updated.getId());
model.update(updated.getCode(), updated.getName());
model.updatePrice(updated.getRetailPrice());
model.updateMaterials(updated.getMaterials());
model.updateModels(updated.getModels());
LOGGER.debug("Updating sku with information: {}", model);
skuRepository.save(model);
return model;
}
@RequestMapping(value = REQUEST_MAPPING_SKU_DETAILS, method = RequestMethod.GET)
public String findById(@PathVariable(PARAMETER_SKU_ID) Long id, Model uiModel) throws NotFoundException {
LOGGER.debug("Rendering sku page for sku entry with id: {}", id);
Sku found = skuService.findById(id);
LOGGER.debug("Found sku entry with information: {}", found);
uiModel.addAttribute(MODEL_ATTRIBUTE_SKU, found);
return VIEW_SKU_DETAILS;
}
@RequestMapping(value = REQUEST_MAPPING_SKU_EDIT, method = RequestMethod.POST)
public String processUpdateSkuForm(@Valid @ModelAttribute(MODEL_ATTRIBUTE_SKU) SkuDTO dto, BindingResult result, RedirectAttributes attributes) throws NotFoundException {
LOGGER.debug("Updating a sku entry with information: {}", dto);
if (result.hasErrors()) {
LOGGER.debug("Update sku entry form was submitted with validation errors. Redirecting back to form view.");
attributes.addFlashAttribute("org.springframework.validation.BindingResult." + MODEL_ATTRIBUTE_SKU, result);
attributes.addFlashAttribute(MODEL_ATTRIBUTE_SKU, dto);
attributes.addAttribute(PARAMETER_SKU_ID, dto.getId());
return createRedirectViewPath(REQUEST_MAPPING_SKU_EDIT);
}
Sku updated = skuService.update(dto);
LOGGER.debug("Updated the information of a sku entry to: {}", updated);
attributes.addAttribute(PARAMETER_SKU_ID, updated.getId());
return createRedirectViewPath(REQUEST_MAPPING_SKU_DETAILS);
}
答案 0 :(得分:0)
我遇到了同样的问题。
我相信这是因为Spring生成的查询并没有使用&#39; DISTINCT&#39;什么时候加入,但我不知道解决方案。您可以使用Set&lt;&gt;而不是列表&lt;&gt;