Hibernate指未保存的瞬态

时间:2014-10-23 08:50:25

标签: hibernate spring-mvc spring-security

我想我遇到的问题很常见,我已经搜索了类似的问题并尝试了解决方案,但没有一个能够解决问题。我正在使用一个使用hibernate的Spring-MVC应用程序。该应用程序有2个类(也是2个表),Person与Notes有一对多的关系。我想添加一个注释,我收到以下错误。

错误日志:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.journaldev.spring.model.Person
    org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:294)
    org.hibernate.type.EntityType.getIdentifier(EntityType.java:537)
    org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:311)
    org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:321)
    org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:294)
    org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:4243)
    org.hibernate.event.internal.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:546)
    org.hibernate.event.internal.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:232)
    org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:159)
    org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:231)
    org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:102)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)
    org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
    org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)

人物模型:

@Entity
@Table(name="person")
public class Person implements UserDetails{

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_USER");

    @Id
    @Column(name="personid")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "person_seq_gen")
    @SequenceGenerator(name = "person_seq_gen",sequenceName = "person_seq")
    private int id;

  @OneToMany(cascade = CascadeType.ALL,mappedBy = "person1")
    private Set<Notes> notes1;

笔记型号:

   @Entity
    @Table(name="note")
    public class Notes {

        @Id
        @Column(name="noteid")
        @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "note_gen")
        @SequenceGenerator(name = "note_gen",sequenceName = "note_seq")
        private int noteId;

    @ManyToOne
       @JoinColumn(name = "personid")
       private Person person1;

  public Person getPerson1() {
        return person1;
    }

    public void setPerson1(Person person1) {
        this.person1 = person1;
    }

当我使用Spring安全性时,我能够为JSP文件设置一个人,我想在其中添加注释,如下所示:

Notes控制器:

@Controller
public class NoteController {



    private NotesService notesService;

    @Autowired(required=true)
    @Qualifier(value="notesService")
    public void setNotesService(NotesService notesService){this.notesService=notesService;}

  @RequestMapping(value= "/note/add", method = RequestMethod.GET)
    public String addNote(@ModelAttribute("notes") Notes p,@AuthenticationPrincipal Person person){
        p.setPerson1(person);
        this.notesService.addNote(p);
        return "redirect:/";
    }

NotesDAOimpl:

@Transactional
@Repository
public class NotesDAOImpl implements NotesDAO{



    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sf){
        this.sessionFactory = sf;
    }


    @Override
    public void addNote(Notes notes, int id) {
 Person person;
        notes.setPerson1(person);

       Session session = this.sessionFactory.getCurrentSession();
       session.saveOrUpdate(notes);
    }

PersonDAOImpl

@Transactional
@Repository
public class PersonDAOImpl implements PersonDAO {



    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sf){
        this.sessionFactory = sf;
    }

    @Override
    public void addPerson(Person p) {
        Notes notes;
        p.setNotes1(notes);
        Session session = this.sessionFactory.getCurrentSession();
        session.saveOrUpdate(p);

    }

此代码现在只在数据库中创建空白人员,如果我停止保存此人,则会出现上述错误。任何指针都会很好。谢谢。

2 个答案:

答案 0 :(得分:0)

你应该在双方的人和笔记之间设置关联, 例如person.setNotes(..),notes.setPersonId(...)

如果以这种方式指定对象之间的关联,则保存级联应该正常工作,并且关联的两端都应保存在数据库中。

祝你好运

答案 1 :(得分:0)

有许多不同类型的@OneToMany和@ManyToOne关系,它不仅取决于哪一方管理引用,还取决于关系是单向还是双向。请在这里查看what-is-the-difference-between-unidirectional-and-bidirectional-associationsHow to map collections