2

First of all I have two tables job, category which are in diagram as

Job to Cat

and my entities are :

@Entity
@Table( name = TableName.JOB_TABLE)
public class Job {


    @Id
    @GeneratedValue
    private Integer id;

    private String title;

    private String description;     

    @OneToMany(mappedBy = "job")
    private List<Category> categories;

    // omitting setters an getters for brevity  

}

and

@Entity
@Table( name = TableName.CATEGORY_TABLE)
public class Category {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    @ManyToOne
    @JoinColumn(name = "job_id")
    private Job job;

    // omitting setters an getters for brevity  

}

JobService is

@Service
public class JobService implements IDatabaseCrud<Job>{

    @Autowired
    private JobRepository jobRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    public void saveCategory(Job job) {
        List<Category> categories = job.getCategories();
        for (Category category : categories) {
            category.setJob(job);
            categoryRepository.save(category);
        }
    }

    @Override
    public void save(Job obj) {
        // TODO Auto-generated method stub      
        jobRepository.save(obj);
        saveCategory(obj);
    }
}

now I don't have any idea to save new job where I've to save one Job with many categories selected from list.

<form:form commandName="job">
   <form:input path="title"/><br>
    <form:input path="company"/><br>
    <form:input path="location"/><br>
    <form:input path="url"/><br>
    <form:input path="email"/><br>
    <form:input path="description"/><br>
    <form:select path="categories">
    <form:options items="${categories}" itemValue="id" itemLabel="name"/>
    </form:select><br>
    <form:input path="createdAt"/><br>
    <form:input path="toApply"/><br>
    <input type="submit" value="Add Job">
</form:form>

the above form is not submitting data to controller and gives error HTTP Status 400 -The request sent by the client was syntactically incorrect. following controller I want to save these details to DB

@Controller
public class JobController {

    private static final Logger logger = LoggerFactory.getLogger(JobController.class);

    @Autowired
    private JobService jobService;

    @Autowired
    private CategoryService categoryService;

    @ModelAttribute("job")
    public Job constructJob() {
        return new Job();
    }

    @RequestMapping(value = "/jobs", method = RequestMethod.GET)
    public String showJobs(Model model) {
        model.addAttribute("jobs", jobService.findAll());
        return "jobs";
    } 

    @RequestMapping(value = "/jobs/{id}", method = RequestMethod.GET)
    public String showJobDetail(Model model, @PathVariable Integer id) {
        model.addAttribute("job", jobService.findJobWithCategories(id));
        return "job-detail";
    } 

    @RequestMapping(value = "/show-add-job", method = RequestMethod.GET)
    public String showJobForm(Model model) {
        model.addAttribute("categories", categoryService.findAll());
        return "add-job";
    } 

    @RequestMapping(value = "/show-add-job", method = RequestMethod.POST)
    public String addJobDetail(@ModelAttribute("job") Job job) {
        ///jobService.save(job);
        List<Category> categories = job.getCategories();
        for (Category category : categories) {
            logger.info("DEBUG job object", category);
        }
        return "redirect:/jobs";
    } 

}

with the above stuff I'm unable to save job with categories when I submit the form I get HTTP Status 400. is some thing wrong in form. This is URL to that project.

Arshad Ali
  • 3,082
  • 12
  • 56
  • 99
  • your web.xml does not have spring dispatcher servlet defined, please add definition and then check. – Krishnat Molawade Sep 07 '15 at 09:13
  • @KrishnatMolawade there is no need of spring dispatcher servlet definition in web.xml when I'm using [WebApplicationInitializer](http://docs.spring.io/autorepo/docs/spring-framework/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html). – Arshad Ali Sep 07 '15 at 13:14
  • Ohh, my bad...thanks – Krishnat Molawade Sep 07 '15 at 16:54
  • error 400 ( bad request) means that something is wrong with your http request. My suggestion is that when you submit the form params, these params cannot be bind to `Job` object. please share your form params from http request. – Nikolay Rusev Sep 08 '15 at 07:45
  • @NikolayRusev I've provided a link to project please have a look at that and fix the issue accordingly it will be a great favor of you. Please. – Arshad Ali Sep 09 '15 at 14:31
  • 1
    What view are you showing us? Is that "add-job"? – Brian Kent Sep 09 '15 at 15:10
  • @BrianKent Yes that is add-job view! – Arshad Ali Sep 09 '15 at 15:13
  • 1
    I don't see a link in the views to actually get to "/show-add-job". Are you just navigating there manually? – Brian Kent Sep 09 '15 at 15:23
  • Yes I was navigating manually! – Arshad Ali Sep 09 '15 at 15:24
  • If you debug or add a log message, can you confirm if your form submission request actually enters `addJobDetail(...)`? And if not, have you tried adding a `BindingResult result` parameter to try to get more information? – Brian Kent Sep 09 '15 at 15:28
  • no I have found that form submission request does not enter to addJobDetail(...) and it only shows the error massage, and BindingResult result parameter is not added. – Arshad Ali Sep 09 '15 at 15:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89183/discussion-between-arshad-ali-and-brian-kent). – Arshad Ali Sep 09 '15 at 15:50

2 Answers2

2

The problem you are getting is related to how you bind the categories, in fact you need to help the framework resolve them, e.g. with a help of WebDataBinder. You should add something like

   @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Category.class,
                new PropertyEditorSupport() {

                    @Override
                    public void setAsText(String text) {
                        // replace the dao with your appropriate repository call
                        Category category = dao.find(Category.class,
                                Integer.parseInt(text));
                        setValue(category);
                    }
                });
    }

about the createdAt

the trouble you're facing there is that you need to tell the framework in which format are you entering the date. For example, if you are passing the date in the format of yyyy\MM\dd, than it will simply work. If you are using some other format it will suffice to annotate the property with @DateTimeFormat. A concrete example, you can annotate your property inside the Job class with

@DateTimeFormat(iso= DateTimeFormat.ISO.DATE)
@Column(name = "created_at")
private Date createdAt;

DateTimeFormat.ISO.DATE expects a date in yyyy-MM-dd format, or use a pattern attribute, and the format you prefer

Master Slave
  • 27,771
  • 4
  • 57
  • 55
  • Where should I put this `@InitBinder` method? it will be great that grab my project and make changes and let me know Please! – Arshad Ali Sep 09 '15 at 15:55
  • add it to your `JobController` class, also if you're passing a date in some other format than `yyyy\MM\dd` you should handle it with an annotation. Will add to the response. Otherwise, your code is fine – Master Slave Sep 09 '15 at 15:57
  • I have one question that is how to save current date instead of getting form input! – Arshad Ali Sep 10 '15 at 02:27
  • I'm still have trouble in setting `createdAt`, that gives error _HTTP Status 400 -The request sent by the client was syntactically incorrect_ – Arshad Ali Sep 10 '15 at 02:33
  • I don't know is this good or bad idea but I have updated to `@RequestMapping(value = "/show-add-job", method = RequestMethod.POST) public String addJobDetail(@ModelAttribute("job") Job job) { job.setCreatedAt(new Date());// Adding date here not from form jobService.save(job); return "redirect:/jobs"; } ` – Arshad Ali Sep 10 '15 at 13:56
  • the above logic solves my problem and by the way thank you very much for this precious help. – Arshad Ali Sep 10 '15 at 13:57
0

Hello i checked out your code and found that you have three issues: one is related to submission of the date field - createdAt, the other one is with the applyTo field and the other one is with categories field.

About the problem with dates you should check documentation for spring @InitBinder. Here is a good SO thread for it. Basic problem is that spring don't know how to bind date to String.

Other problem with categories field is that you should implement a Converter that will convert categoryId which is a number to Category class. see here good thread.

if you remove all three fields - applyTo,createdAt and categories, your form submission will work. but if you want to work as expected please implement @initBinder for date and Converter for categories

Community
  • 1
  • 1
Nikolay Rusev
  • 4,060
  • 3
  • 19
  • 29