I have a complex entity:
public class Task {
@OneToOne(orphanRemoval=true, mappedBy="parent")
@Cascade(value = CascadeType.ALL) (org.hibernate.annotations ... package)
private Executor executor;
...
}
public class Executor {
@OneToOne
@JoinColumn
private Task parent;
@ManyToOne
@Cascade(value = CascadeType.ALL)
private List<Property> propList = new LinkedList<Property>();
}
Generally, it's a 'Task', which forms an 'Executor', and 'Executor' is filled in with some specific properties.
If I do this in a regular manner, meaning:
@Service
public class Service {
@PostConstruct
private void test() {
Task task = new Task();
Executor ex = new Executor();
List<Property> props = ex.getProperties();
... forming and adding some properties
taskDao.saveAndFlush(task);
}
Everything is fine and the Task get's properly stored.
But since this is simplified, and I need to store the Task the moment I get one, meaning, right after the definition, and store it (flushing, no flushing, dividing into a separate method with transactioning),
@Service
public class Service {
@PostConstruct
private void test() {
Task task = new Task();
taskDao.saveAndFlush(task); // no change in the exception if I properly move this out to a separate method with @Transactional
Executor ex = new Executor();
List<Property> props = ex.getProperties();
... forming and adding some properties
taskDao.saveAndFlush(task);
}
I get the "unsaved transaction", which is pointing to the second "saveAndFlush".
And this is only achievable if I fill in the Properties, meaning that commenting out the "forming properties" part, everything is working well.
The cascade is ALL (the full list, held in org.hibernate.annotations...), so I'm having doubts for forgetting to specify "Cascade".
saveAndflush
does not change the entity to managed state, you need to use managed entity returned by this method. Try this solution:
@PostConstruct
private void test() {
Task task = new Task();
task = taskDao.saveAndFlush(task); // reassign
Executor ex = new Executor();
List<Property> props = ex.getProperties();
... forming and adding some properties
taskDao.saveAndFlush(task);
}