Spring, 1 form 2 entities











up vote
0
down vote

favorite












I want to save 2 x entity, author and book from a single form. How I can do this?



I know I must first save author, but I don't know how. Author is in a one-to-many relationship with book.



I have set cascadetype.ALL. I'm using thymeleaf.



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" th:field="*{author.name}"/>

<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


authorCommand



@Setter
@Getter
@NoArgsConstructor
public class AuthorCommand {
private long id;
private String name;
private String lastName;
private Set<BookCommand> bookCommandSet = new HashSet<>();
}


bookCommand



@Setter
@Getter
@NoArgsConstructor
public class BookCommand {
private long id;
private String title;
private String isbn;
private String description;
private Set<CategoryCommand> categorySet = new HashSet<>();
private AuthorCommand author;
}


bookController



@RequestMapping(value = "book/new", method = RequestMethod.GET)
public String newBook(Model model){
model.addAttribute("book", new BookCommand());
return "book/form";
}

@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand){
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}









share|improve this question
























  • You basically have two options: 1) create the author first, i.e. use 2 forms and only allow the user to select an existing author for a new book or 2) handle new/unknown authors in your controller, especially when the autor's id is unknown (long can't be null so "unknown" must be represented by some other value, e.g. -1).
    – Thomas
    Nov 19 at 13:29















up vote
0
down vote

favorite












I want to save 2 x entity, author and book from a single form. How I can do this?



I know I must first save author, but I don't know how. Author is in a one-to-many relationship with book.



I have set cascadetype.ALL. I'm using thymeleaf.



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" th:field="*{author.name}"/>

<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


authorCommand



@Setter
@Getter
@NoArgsConstructor
public class AuthorCommand {
private long id;
private String name;
private String lastName;
private Set<BookCommand> bookCommandSet = new HashSet<>();
}


bookCommand



@Setter
@Getter
@NoArgsConstructor
public class BookCommand {
private long id;
private String title;
private String isbn;
private String description;
private Set<CategoryCommand> categorySet = new HashSet<>();
private AuthorCommand author;
}


bookController



@RequestMapping(value = "book/new", method = RequestMethod.GET)
public String newBook(Model model){
model.addAttribute("book", new BookCommand());
return "book/form";
}

@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand){
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}









share|improve this question
























  • You basically have two options: 1) create the author first, i.e. use 2 forms and only allow the user to select an existing author for a new book or 2) handle new/unknown authors in your controller, especially when the autor's id is unknown (long can't be null so "unknown" must be represented by some other value, e.g. -1).
    – Thomas
    Nov 19 at 13:29













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I want to save 2 x entity, author and book from a single form. How I can do this?



I know I must first save author, but I don't know how. Author is in a one-to-many relationship with book.



I have set cascadetype.ALL. I'm using thymeleaf.



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" th:field="*{author.name}"/>

<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


authorCommand



@Setter
@Getter
@NoArgsConstructor
public class AuthorCommand {
private long id;
private String name;
private String lastName;
private Set<BookCommand> bookCommandSet = new HashSet<>();
}


bookCommand



@Setter
@Getter
@NoArgsConstructor
public class BookCommand {
private long id;
private String title;
private String isbn;
private String description;
private Set<CategoryCommand> categorySet = new HashSet<>();
private AuthorCommand author;
}


bookController



@RequestMapping(value = "book/new", method = RequestMethod.GET)
public String newBook(Model model){
model.addAttribute("book", new BookCommand());
return "book/form";
}

@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand){
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}









share|improve this question















I want to save 2 x entity, author and book from a single form. How I can do this?



I know I must first save author, but I don't know how. Author is in a one-to-many relationship with book.



I have set cascadetype.ALL. I'm using thymeleaf.



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" th:field="*{author.name}"/>

<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


authorCommand



@Setter
@Getter
@NoArgsConstructor
public class AuthorCommand {
private long id;
private String name;
private String lastName;
private Set<BookCommand> bookCommandSet = new HashSet<>();
}


bookCommand



@Setter
@Getter
@NoArgsConstructor
public class BookCommand {
private long id;
private String title;
private String isbn;
private String description;
private Set<CategoryCommand> categorySet = new HashSet<>();
private AuthorCommand author;
}


bookController



@RequestMapping(value = "book/new", method = RequestMethod.GET)
public String newBook(Model model){
model.addAttribute("book", new BookCommand());
return "book/form";
}

@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand){
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}






java spring thymeleaf






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 14:40









MTCoster

2,68521838




2,68521838










asked Nov 19 at 13:21









Paweł Hozer

21




21












  • You basically have two options: 1) create the author first, i.e. use 2 forms and only allow the user to select an existing author for a new book or 2) handle new/unknown authors in your controller, especially when the autor's id is unknown (long can't be null so "unknown" must be represented by some other value, e.g. -1).
    – Thomas
    Nov 19 at 13:29


















  • You basically have two options: 1) create the author first, i.e. use 2 forms and only allow the user to select an existing author for a new book or 2) handle new/unknown authors in your controller, especially when the autor's id is unknown (long can't be null so "unknown" must be represented by some other value, e.g. -1).
    – Thomas
    Nov 19 at 13:29
















You basically have two options: 1) create the author first, i.e. use 2 forms and only allow the user to select an existing author for a new book or 2) handle new/unknown authors in your controller, especially when the autor's id is unknown (long can't be null so "unknown" must be represented by some other value, e.g. -1).
– Thomas
Nov 19 at 13:29




You basically have two options: 1) create the author first, i.e. use 2 forms and only allow the user to select an existing author for a new book or 2) handle new/unknown authors in your controller, especially when the autor's id is unknown (long can't be null so "unknown" must be represented by some other value, e.g. -1).
– Thomas
Nov 19 at 13:29












1 Answer
1






active

oldest

votes

















up vote
0
down vote













Well, you can always send additional parameters aside from your model, using the name tag in your inputs.



HTML



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" name="author"/>
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


Controller



@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand,
@RequestParam("author") String name,
BindingResult bindingResult){
if( bindingResult.hasErrors()) {
return "redirect:/book/new";
}

Author author = new Author();
author.setName(name);
authorService.saveAuthor(author);
savedBook.setAuthor(author);
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}


A few things to considered, I don't know how you are separating the author name, but I would add two different inputs, one for the first name and another for the last name. Also, I am assuming the author's id is using @GeneratedValue.






share|improve this answer























  • When I try your solve, I got error : Validation failed for object='book'. Error count: 1
    – Paweł Hozer
    Nov 19 at 20:22










  • Yes, author's id is using @generatedvalue
    – Paweł Hozer
    Nov 19 at 20:23










  • Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
    – Alain Cruz
    Nov 19 at 20:29











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375549%2fspring-1-form-2-entities%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













Well, you can always send additional parameters aside from your model, using the name tag in your inputs.



HTML



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" name="author"/>
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


Controller



@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand,
@RequestParam("author") String name,
BindingResult bindingResult){
if( bindingResult.hasErrors()) {
return "redirect:/book/new";
}

Author author = new Author();
author.setName(name);
authorService.saveAuthor(author);
savedBook.setAuthor(author);
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}


A few things to considered, I don't know how you are separating the author name, but I would add two different inputs, one for the first name and another for the last name. Also, I am assuming the author's id is using @GeneratedValue.






share|improve this answer























  • When I try your solve, I got error : Validation failed for object='book'. Error count: 1
    – Paweł Hozer
    Nov 19 at 20:22










  • Yes, author's id is using @generatedvalue
    – Paweł Hozer
    Nov 19 at 20:23










  • Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
    – Alain Cruz
    Nov 19 at 20:29















up vote
0
down vote













Well, you can always send additional parameters aside from your model, using the name tag in your inputs.



HTML



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" name="author"/>
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


Controller



@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand,
@RequestParam("author") String name,
BindingResult bindingResult){
if( bindingResult.hasErrors()) {
return "redirect:/book/new";
}

Author author = new Author();
author.setName(name);
authorService.saveAuthor(author);
savedBook.setAuthor(author);
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}


A few things to considered, I don't know how you are separating the author name, but I would add two different inputs, one for the first name and another for the last name. Also, I am assuming the author's id is using @GeneratedValue.






share|improve this answer























  • When I try your solve, I got error : Validation failed for object='book'. Error count: 1
    – Paweł Hozer
    Nov 19 at 20:22










  • Yes, author's id is using @generatedvalue
    – Paweł Hozer
    Nov 19 at 20:23










  • Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
    – Alain Cruz
    Nov 19 at 20:29













up vote
0
down vote










up vote
0
down vote









Well, you can always send additional parameters aside from your model, using the name tag in your inputs.



HTML



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" name="author"/>
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


Controller



@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand,
@RequestParam("author") String name,
BindingResult bindingResult){
if( bindingResult.hasErrors()) {
return "redirect:/book/new";
}

Author author = new Author();
author.setName(name);
authorService.saveAuthor(author);
savedBook.setAuthor(author);
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}


A few things to considered, I don't know how you are separating the author name, but I would add two different inputs, one for the first name and another for the last name. Also, I am assuming the author's id is using @GeneratedValue.






share|improve this answer














Well, you can always send additional parameters aside from your model, using the name tag in your inputs.



HTML



<form th:object="${book}" th:action="@{/book/}" method="post">
<input type="hidden" class="form-control" th:field="*{id}"/>
<label>title</label>
<input type="text" class="form-control" th:field="*{title}"/>
<label>isbn</label>
<input type="text" class="form-control" th:field="*{isbn}"/>
<label>description</label>
<input type="text" class="form-control" th:field="*{description}"/>
<label>cat</label>
<ul>
<li th:each="category : ${book.getCategorySet()}" th:text="category.getCategory()"></li>
</ul>
<label>author</label>
<input type="text" class="form-control" name="author"/>
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</form>


Controller



@RequestMapping(value = "book", method = RequestMethod.POST)
public String saveOrUpdate(@ModelAttribute("book") BookCommand bookCommand,
@RequestParam("author") String name,
BindingResult bindingResult){
if( bindingResult.hasErrors()) {
return "redirect:/book/new";
}

Author author = new Author();
author.setName(name);
authorService.saveAuthor(author);
savedBook.setAuthor(author);
BookCommand savedBook = bookService.saveBookCommand(bookCommand);
return "redirect:/book/show/"+savedBook.getId();
}


A few things to considered, I don't know how you are separating the author name, but I would add two different inputs, one for the first name and another for the last name. Also, I am assuming the author's id is using @GeneratedValue.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 19 at 20:28

























answered Nov 19 at 17:52









Alain Cruz

1,6841818




1,6841818












  • When I try your solve, I got error : Validation failed for object='book'. Error count: 1
    – Paweł Hozer
    Nov 19 at 20:22










  • Yes, author's id is using @generatedvalue
    – Paweł Hozer
    Nov 19 at 20:23










  • Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
    – Alain Cruz
    Nov 19 at 20:29


















  • When I try your solve, I got error : Validation failed for object='book'. Error count: 1
    – Paweł Hozer
    Nov 19 at 20:22










  • Yes, author's id is using @generatedvalue
    – Paweł Hozer
    Nov 19 at 20:23










  • Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
    – Alain Cruz
    Nov 19 at 20:29
















When I try your solve, I got error : Validation failed for object='book'. Error count: 1
– Paweł Hozer
Nov 19 at 20:22




When I try your solve, I got error : Validation failed for object='book'. Error count: 1
– Paweł Hozer
Nov 19 at 20:22












Yes, author's id is using @generatedvalue
– Paweł Hozer
Nov 19 at 20:23




Yes, author's id is using @generatedvalue
– Paweł Hozer
Nov 19 at 20:23












Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
– Alain Cruz
Nov 19 at 20:29




Are you validating your entity? If you are validating your book entity and you are expecting your author to be not null, your binding will fail.
– Alain Cruz
Nov 19 at 20:29


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375549%2fspring-1-form-2-entities%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

Origin of the phrase “under your belt”?