TergOfSky
TergOfSky

Reputation: 107

hibernate: persist error with detached entity

I have a problem that I don't understand. I have a few entities:

Scenario entity

@Entity
@Table(name = "scenario")
public class Scenario {

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

@Column(name = "title", nullable = false)
private String title;

@NotNull
@DateTimeFormat(pattern = "dd/MM/yyyy")
@Column(name = "creation_date", nullable = false)
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate creationDate;

@OneToMany(mappedBy = "scenario")
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Section> sectionList = new HashSet<Section>();

@ManyToOne
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "id", nullable = false)
private User user;

@OneToMany(mappedBy = "scenario", orphanRemoval=true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Plot> plotList = new HashSet<Plot>();

Plot Entity

@Entity
@Table(name = "Plot")
public class Plot {

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

@Column(name = "name", nullable = false)
private String name;

@Column(name = "description")
private String description;

@ManyToOne
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "id", nullable = false)
private Scenario scenario;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "plot_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
        @JoinColumn(name = "plot_id") })
private Set<Role> roles = new HashSet<Role>();

And the controller

@Autowired
UserService userService;

@Autowired
ScenarioService scenarioService;

@Autowired
PlotService plotService;

@RequestMapping(value = { "/scenario-{id}-newPlot" }, method = RequestMethod.GET)
public String newPlot(ModelMap model, @PathVariable int id) {
    Plot plot = new Plot();
    Scenario scenario = scenarioService.findById(id);
    model.addAttribute("scenario", scenario);
    model.addAttribute("plot", plot);
    model.addAttribute("edit", false);
    return "plotform";
}

@RequestMapping(value = { "/scenario-{id}-newPlot" }, method = RequestMethod.POST)
public String savePlot(@Valid Plot plot, BindingResult result, ModelMap model, @PathVariable int id) {

    if (result.hasErrors()) {
        System.out.println(result.toString());
        return "plotform";
    }
    model.addAttribute("success",
            "Plot " + plot.getName() + " created successfully");
    plot.setScenario(scenarioService.findById(id));
    System.out.println("Plot " + plot.toString());
    plotService.savePlot(plot);

    return "success";
}

I also have, sevices, daos and forms. The problem is that when I try to save plot from the form I get: Request processing failed; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.btw.spindle.model.Plot

I dont get how is it detached and how to fix it. I tired adding System.out to check if the neccesary data is being correctly pulled from the form. And also I have the user entity (which I did not add here). The relation between user and scenario is the same (one to many) as between scenario and plot. Creation of scenario works perfectly and creation of plots throws this persist exception.

Any hints ?

Upvotes: 1

Views: 1718

Answers (3)

Gianfranco A.
Gianfranco A.

Reputation: 29

There are multiple reasons that could cause this exception. The basic idea behind this exception is that the object which you are trying to persist is not in the persistant state.

Can you check if the Plot object has alreay the ID before you save or persist it?

EDIT

You solved, perfect.

Upvotes: 1

TergOfSky
TergOfSky

Reputation: 107

Ok MeewU was right. The problem was because the object had a set up id before being persisted. The reason for that was:

@RequestMapping(value = { "/scenario-{id}-newPlot" }, method = RequestMethod.GET)
public String newPlot(ModelMap model, @PathVariable int id) {

I used it to pass the scenarios ID to add ot in next step to the plot. But it turnes out that the id of scenario was automaticly set as plots id. I changed the variable name to "scenario" and the id is not being set up any longer and persist goes as planned

Upvotes: 1

karim mohsen
karim mohsen

Reputation: 2254

The error occurs because the object has an ID . Hibernate distinguishes between transient and detached objects and persist works only with transient objects(Objects with no ID). If persist concludes the object is detached (which it will because of the ID ), it will return that error

org.hibernate.PersistentObjectException: detached entity passed to persist

I think you need to use saveOrUpdate() instead of save() / persist()

See this link and this answer

Upvotes: 0

Related Questions