In my current spring project, my forms are implemented with a structure like this:
<form class="form" id="Pagina" role="form" method="POST" action="/loja/Pagina/cadastra" enctype="multipart/form-data"> ... </form>
and it is processed on the server by this method:
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(); }
services
@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)") @Transactional public E cadastra(E e, MultipartFile file, MultipartFile icone, MultipartFile[] screenshot) { return dao.persist(e); }
My problem is that there is such a field in the form:
<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>
which displays such an attribute in the entiy class:
@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;
If the parameters inside look like this:
<option value="">.</option> <option value="...">...</option>
If I submit the form with the empty parameter selected, I get this error:
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
but if, for example, insert the record manually into the database (in my case, using pgAdmin3) and select this element in the element, the form will be submitted without errors.
Can someone tell me how I can fix this to allow me to submit a form with or without selected data from <select> .
UPDATE
for the Pagina class:
@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; }
UPDATE 2
PaginaEditor.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); } } }
added to my controller:
@InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Pagina.class, new PaginaEditor()); }