gpt4 book ai didi

spring - 提交带有选择字段的表单时出错

转载 作者:行者123 更新时间:2023-12-03 12:34:53 25 4
gpt4 key购买 nike

在我当前的 spring 项目中,我的表单使用如下结构实现:

<form class="form" id="Pagina" role="form" method="POST" action="/loja/Pagina/cadastra" enctype="multipart/form-data">
...
</form>

并通过以下方法在服务器中处理:

Controller
@RequestMapping(value="cadastra", method=RequestMethod.POST)
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
public E cadastra(@ModelAttribute("object") E object, BindingResult result, @RequestParam(value="file", required=false) MultipartFile file, @RequestParam(value="icone", required=false) MultipartFile icone, @RequestParam(value="screenshot", required=false) MultipartFile screenshot[]) throws Exception {
E ret = serv.cadastra(object, file, icone, screenshot);
if (ret != null)
return ret;
else
throw new Exception();
}

服务
@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)")
@Transactional
public E cadastra(E e, MultipartFile file, MultipartFile icone, MultipartFile[] screenshot) {
return dao.persist(e);
}

我的问题是当表单有这样的字段时:
<label>pagina</label>
<select name="pagina.id" class="form-control select" data-lista="/loja/Pagina/listagem.json">
...
</select>

<label>produto</label>
<select name="produto.id" class="form-control select" data-lista="/loja/Produto/listagem.json">
...
</select>

它在实体类中映射了这样的属性:
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="pagina_mae", nullable = true)
@Order(value=5)
@Select(name="pagina", ordem = 5)
@Sidebar
private Pagina pagina;

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="produto_mae", nullable = true)
@Order(value=6)
@Select(name="produto", ordem = 6)
@Sidebar
private Produto produto;

里面的选项看起来像这样:
<option value="">.</option>
<option value="...">...</option>

如果我在选择空白选项的情况下提交表单,则会收到此错误:
object references an unsaved transient instance - save the transient instance before flushing: com.spring.loja.model.pagina.persistence.model.Pagina; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.spring.loja.model.pagina.persistence.model.Pagina

但是,例如,如果在数据库中手动插入一条记录(在我的情况下,使用 pgAdmin3),并在选择中选择此项,则提交的表单不会出错。

任何人都可以告诉我如何解决这个问题,以允许我提交带有或不带有来自 <select> 的选定数据的表单。 .

更新

类(class)代码 Pagina :
@Entity
@Table(name="pagina")
@MainForm(grupo = 2, icone = "file")
public class Pagina extends ModelEntity {

@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;

@Column(name = "nome", unique = true)
@Order(value=1)
@Input(type="hidden", name="nome", ordem = 1)
private String nome;

@Column(name = "titulo", nullable = false)
@Order(value=2)
@Input(name="titulo", ordem = 2)
private String titulo;

@Column(name = "descricao", length=65535)
@Order(value=4)
@Textarea(name="descricao", ordem = 4)
private String descricao;

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="pagina_mae", nullable = true)
@Order(value=5)
@Select(name="pagina", ordem = 5)
@Sidebar
private Pagina pagina;

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="produto_mae", nullable = true)
@Order(value=6)
@Select(name="produto", ordem = 6)
@Sidebar
private Produto produto;
}

更新 2

页面编辑器.java
@Component
public class PaginaEditor extends PropertyEditorSupport {

@Inject
private PaginaService paginaService;

@Override
public void setAsText(String text) {
if (!text.isEmpty()) {
Pagina pagina = paginaService.getObject(text);
setValue(pagina);
}
}

}

添加到我的 Controller 的方法:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Pagina.class, new PaginaEditor());
}

最佳答案

在 Spring MVC 中选择是棘手的。

我认为您的问题是,当您的主要实体进入要持久化的数据层时,关系不存在。

尝试调试并检查上述肯定是否正确。

有两种方法可以进行排序。

让我们假设联系人系统中有公司/联系人关系。
一个公司有很多联系人,一个联系人有一个公司。

公司片段。

// package declaration imports and all
@Entity
@Table(name = "company")
public class Company {

private String name;

@OneToMany(mappedBy = "company")
private List<Contact> contacts = new ArrayList<Contact>();

// getter and setters and any extra stuff you fancy putting here

}

联系方式片段
// package declaration imports and all
@Entity
@Table(name = "contact")
public class Contact {

private String name;

@ManyToOne
private Company company;

// getter and setters and any extra stuff you fancy putting here

}

还有一个带有选择的jsp片段。
我们假设模型中有一个“联系人”对象和一个客户列表。
<form:form modelAttribute="contact">
<form:input path="name" />
<form:select path="customer" items="${customers}" itemValue="id" itemLabel="name" />
</form:form>

有了这段代码,您就可以像这样使用 PropertyEditor。
@Component
public class CustomerEditor extends PropertyEditorSupport {

@Inject
private CustomerService customerService;

@Override
public void setAsText(String text) {
if (StringUtils.isNotBlank(text)) {
Customer customer = this.customerService.findById(Integer
.valueOf(text));
this.setValue(customer);
}
}

}

并像这样在您的 Spring Context 中注册。
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Customer.class, this.customerEditor);
}

这里发生的事情是,每当 Spring 找到 Customer 类型的对象时,它都会使用 PropertyEditor 将(在本例中)Id 转换为对象,并根据联系人(在本例中)获取到数据层(Hibernate)的类型),适当的 Customer 实体将像 Larry 一样快乐地等待。

这是自动的方式来做到这一点。

另一种方法是创建一个表单/DTO 或您想调用的任何内容,并添加包括 customerId 字段(在本例中)的字段,并在保存实体之前转换您自己。

我希望我能正确理解你的问题,因为我花了好几分钟来写这篇文章...... :)

关于spring - 提交带有选择字段的表单时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25677163/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com