-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: FK on ManyToOne is null when saved
PostPosted: Sun May 28, 2017 1:05 am 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
Hello,

One of my child entitys is saving with a null FK.

The setup should be like so:

Event has ManyToOne with Project (bidirectional)
Project has OneToMany with Task (bidirectional)
Task has ManyToOne with Plan.

I want to be able to save a Event and persist both the Project and the task (note Task is not a direct child of Episode, but a child of Project - which in turn is a child of event)

My Entity setup:

Code:
@Entity
public class Event {

    public Event() {}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //
    @ManyToOne(cascade = CascadeType.ALL)
    private Project project;


@Entity
public class Project {

    public Project() {}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //

    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Task> tasks;

    @OneToMany(mappedBy = "project")
    private List<Event> event;


@Entity
public class Task {

    public Task() {}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //
    @ManyToOne
    private Project project;



When I save a Event the task and project get saved, but the project_id on task is blank.

Part of the problem could be the way I am dealing with this in my UI...I have two screens one for Event and one for Project - which also allows you to add tasks.

In the controller the POST and GET for Project add's the Event to the model which is convenient since my Project screen needs some details from Event to display, as well as project and tasks. Would I be better to add project to the model instead of event but then how would I get the event details that I also want to display on the project screen?

-AL


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Mon May 29, 2017 1:25 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Quote:
I want to be able to save a Event and persist both the Project and the task (note Task is not a direct child of Episode, but a child of Project - which in turn is a child of event)


Cascade the entity state transitions from Child to Parent does not make any sense. The Child entity has a FK that points to a Parent entity. Therefore, when the Child is to be saved, the Pparent must already be in the DB.

The problem is that you just want to pass whatever you get from the UI and persist it automatically. However, why do you think there is a Service layer in between? So, if you get a product.name, you need to check if the Product exists. If it does, you use that for the Event. If it doesn't, you persist it and pass the reference to the Event.


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Mon May 29, 2017 1:38 am 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
If I have a relationship between Event and Project of Event (Many) to Project (One) and I create a Event. Then in my form view I populate the details of Event and save.

A bit later I open a form Project view and pass in the Event I can display some details from the event, and also populate the Project details.

The event is passed backed to the controller and saved.

The correct relationships (FK on Event being project_id) are saved - is my understanding of this correct - because this part of my project works.


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Mon May 29, 2017 1:42 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
The flow looks good, but you still have to apply what Ii told you previously. You need to set the Project reference when saving an Event and the reference must be fetched from the Persistence Context.


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Mon May 29, 2017 1:49 am 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
So how is that I can create load a project form (event is in the model) and save the data returned (save event) and the details of the project are saved without any setting of references.


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Mon May 29, 2017 3:34 pm 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
Ok, so this is my crude attempt to save the objects when it comes back from view:

Code:
    @Override
    @Transactional
    public Event submitProject(Event event) {
        Project tempProject = event.getProject();
        List<Task> tempTasks = event.getProject().getTasks();
       
        // SAVE PROJECT & TASKS
        tempTasks = taskRepository.save(tempTasks);
        tempProject.setTasks(tempTasks);
        tempProject = planRepository.save(tempPlan);

        // FOR EACH TASK THAT DOESNT HAVE PROJECT_ID - ADD IT
        for (Task tasks : tempTasks) {
            if (tasks.getProject() == null) {
                tasks.setProject(tempProject);
            }
        }

        //ADD TASKS TO PROJECT
        tempProject.setTasks(tempTasks);

        // SAVE TEMP PROJECT BACK TO EVENT
        event.setPlan(tempPlan);

        // SAVE EVENT
        return eventRepository.save(event);

    }


I have experiemtned with this code and I get several copies of each new task added to the task table - the last of the several copies has project_id against it (small win) - but I obviously dont want several copies.

At other times on the eventRepository.save I get a error:

Code:
MergeContext#attempt to create managed -> managed mapping with different entities: [com.example.dao.Event#4]; [com.example.dao.Event#4]; nested exception is java.lang.IllegalStateException: MergeContext#attempt to create managed -> managed mapping with different entities: [com.example.dao.#4]; [com.example.dao.Event#4]]


Reading here https://stackoverflow.com/questions/427 ... ties-error give me a hint as to whats going wrong - but I dont understand how to impliment solution.

How do I fix the multiple saves and this error


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Tue May 30, 2017 4:17 am 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
For the benefit of anyone else who comes across this thread my entities ended up being:



Post subject: FK on ManyToOne is null when saved Reply with quote
Hello,

One of my child entitys is saving with a null FK.

The setup should be like so:

Event has ManyToOne with Project (bidirectional)
Project has OneToMany with Task (bidirectional)
Task has ManyToOne with Plan.

I want to be able to save a Event and persist both the Project and the task (note Task is not a direct child of Episode, but a child of Project - which in turn is a child of event)

My Entity setup:

Code:
@Entity
public class Event {

    public Event() {}
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //
    @ManyToOne(cascade = CascadeType.ALL)
    private Project project;

@Entity
public class Project {

    public Project() {}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //
    @OneToMany(mappedBy = "project", fetch = FetchType.EAGER)
    private List<Task> tasks;

    @OneToMany(mappedBy = "project")
    private List<Event> event;

@Entity
public class Task {

    public Task() {}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //
    @ManyToOne(optional=false)
    @JoinColumn(name="project_id")
    private Project project;


In order to insert the correct references (something with I initally thought Hiberante did auto-magically) I needed some code in my service layer. This is my attempt at it:

Code:
    @Override
    @Transactional
    public Event submitProject(Event event) {
       
        // SAVE PROJECT & TASKS
        List<Event> eventList = new ArrayList<>();
        eventList.add(event);
        event.getProject().setEvent(eventList);

        projectRepository.save(event.getProject());
        taskRepository.save(event.getProject().getTasks());

        // SETUP PROJECT TO KNOW WHAT EVENTS ITS RELATED TO (A COLLETION)
        episode.getPlan().getEpisode();

        // FOR EACH TASK THAT DOESNT HAVE PROJECT_ID - ADD IT
        for (Task tasks : event.getProject().getTasks()) {
            if (tasks.getProject() == null) {
                tasks.setProject(event.getProject());
            }
        }

        // A TEST TO NAVIGATE FROM BOTTOM UP
        List<Task> tempTask = event.getProject().getTasks();
        Task task = tempTask.get(2);
        Project testProject = task.getProject();
        List<Event> testEvent = testProject.getEvent();

        // SAVE EVENT
        return eventRepository.save(event);
    }


If anyone wants to suggest improvements please do.

NB: I have not yet impliemnted a service to get a colletion of the existing events associated to a Project so it just associates the one.


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Sat Jun 03, 2017 8:59 am 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
vlad wrote:
The flow looks good, but you still have to apply what Ii told you previously. You need to set the Project reference when saving an Event and the reference must be fetched from the Persistence Context.


I have done some reading and the more I read your answer (over and over again) its starting to make more sense.

The process workflow I have means the Event gets inserted into the database initally without any Project or Tasks.

Some hours later Project is created and then also Tasks.

Does this change your advice any?

This SO user seems to think JPA can handle all the cascade relationships if its setup property https://stackoverflow.com/questions/442 ... 1_44225635 but you said JPA wouldn't right?


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Sun Jun 04, 2017 4:35 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1628
Location: Romania
Quote:
Does this change your advice any?


Not a bit.

Quote:
This SO user seems to think JPA can handle all the cascade relationships.


I think that @ManyToOne cascading is a code smell. However, you should decide for yourself whose advice it's worth following.


Top
 Profile  
 
 Post subject: Re: FK on ManyToOne is null when saved
PostPosted: Sun Jun 04, 2017 4:52 am 
Beginner
Beginner

Joined: Sun May 07, 2017 11:24 pm
Posts: 29
vlad wrote:
Quote:
Does this change your advice any?


Not a bit.

Quote:
This SO user seems to think JPA can handle all the cascade relationships.


I think that @ManyToOne cascading is a code smell. However, you should decide for yourself whose advice it's worth following.


I think I already have ;-)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.