简体   繁体   中英

object references an unsaved transient instance - save the transient instance before flushing

I have two instances. One is Project, the other is Module. One to Many relationship.

@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "project", uniqueConstraints = { @UniqueConstraint(columnNames = { "name", "version" }) })
public class Project implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "version")
private String projectVersion;
@Column(name = "description")
private String description;
@Column(name = "is_cartridge")
private boolean cartridge;
@Column(name = "manifest")
private String manifest;
@OneToMany(mappedBy = "project", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "project_id")
private Set<Module> modules = new HashSet<Module>();

@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "module", uniqueConstraints = { @UniqueConstraint(columnNames = { "project_id", "name", "module_id" }) })
public class Module implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "module_id")
private String moduleId;
@Column(name = "version")
private String version;
@Column(name = "type")
private String type;
@Column(name = "resource")
private String resource;
@OneToOne
@JoinColumn(name = "default_language_id")
private Locality defaultLocality = new Locality();
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "project_id")
private Project project = new Project();
@OneToMany(mappedBy = "module", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "module_id")
private Set<KeyValue> keyValues = new HashSet<KeyValue>();

I will set the modules into the project. and then use session.save(project) . First time, because there is no record in the database, so the project and modules can be saved into the database. However, the second time, because I don't need to create new project, I only create new modules and then set the modules back to the project.

An exception occurs.

object references an unsaved transient instance - save the transient instance before flushing.

@Transactional
public Project save(Project project) {
    Session session = sessionFactory.openSession();
    try {
        Criteria criteria = session.createCriteria(Project.class).add(
                Restrictions.eq("name", project.getName()));
        List<Project> list = criteria.list();
        if (list.size() == 0) {
            Integer id = (Integer) session.save(project);
            project = get(id);
            return (project);
        } else {
            Project persistedModule = list.get(0).merge(project);
            session.update(persistedModule);
            session.flush();    **// Problem occurs in this line.**
            return (persistedModule);
        }
    } finally {
        session.close();
    }
}

Is there any way to solve this problem? Thank you.

Your mapping is wrong:

  • you have a OneToMany on one side, and a OneToOne on the other side. It should be OneToMany and ManyToOne.
  • you're saying the the OneToMany is mapped by the project field in module, but you also specify a join column. If it's mapped by product, then product defines how the association is mapped. So you must not have a @ JoinColumn annotation on the OneToMany.

You have repeated these errors for other associations, BTW.

You're also calling update() on a project (called persistedModule , which makes things quite confusing) that is attached, since it's the result of a previous merge() call. Updating an attached object is useless. It's already attached, so there's ,no reason to attach it again.

I'm not sure if that will fix your problem, since it's hard to know what the actual problem is without the code and the stack trace, but I would start by fixing these issues

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM