Hibernate递归双向一对多关联

时间:2011-06-08 09:53:13

标签: hibernate spring struts2

我有一个实体可以有0个或同一个实体的子节点。此外,实体可以具有同一实体的0个或一个父级。 表结构是

CREATE TABLE `group` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `parent_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_group_parent1` (`parent_id`),
  CONSTRAINT `fk_group_parent1` FOREIGN KEY (`parent_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
)

我在Group class中有这个注释

@Entity
@Table(name="group")
public class Group implements Serializable {

    private static final long serialVersionUID = 2831577205800506169L;

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

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

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


    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "parent_id", nullable = true)
    private Group parentGroup = null;

    @OneToMany(fetch=FetchType.LAZY, mappedBy = "parentGroup", 
            cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    private Set<Group> childGroups = new HashSet<Group>();

    ... getters/setters

来源:来自Java持久化与hibernate

在我的主代码中,我使用null childGroups

初始化一个组
    // create realm user group      
    Group parent = new Group();
    parent.setName("RealmUserGroup");

    Group child = new Group();

    // add null child to parent
    child.setParentGroup(parent);

    parent.addChildGroup(child);

当我想用groupManager保存时,我收到此错误

2011-06-08 11:20:11,098 DEBUG [AbstractSaveEventListener.java:514] : transient instance of: com.joonts.domain.Group
2011-06-08 11:20:11,098 DEBUG [DefaultMergeEventListener.java:275] : merging transient instance
2011-06-08 11:20:11,099 DEBUG [DefaultMergeEventListener.java:288] : merging transient instance
2011-06-08 11:20:11,099 DEBUG [Cascade.java:116] : processing cascade ACTION_MERGE for: com.joonts.domain.Group
2011-06-08 11:20:11,100 DEBUG [Cascade.java:151] : done processing cascade ACTION_MERGE for: com.joonts.domain.Group
2011-06-08 11:20:11,100 DEBUG [AbstractSaveEventListener.java:153] : saving [com.joonts.domain.Group#<null>]
2011-06-08 11:20:11,100 DEBUG [AbstractSaveEventListener.java:244] : executing insertions
2011-06-08 11:20:11,103 DEBUG [WrapVisitor.java:87] : Wrapped collection in role: com.joonts.domain.Group.childGroups
2011-06-08 11:20:11,103 DEBUG [AbstractSaveEventListener.java:297] : executing identity-insert immediately
2011-06-08 11:20:11,104 DEBUG [AbstractEntityPersister.java:2139] : Inserting entity: com.joonts.domain.Group (native id)
2011-06-08 11:20:11,104 DEBUG [AbstractBatcher.java:389] : about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2011-06-08 11:20:11,105 DEBUG [AbstractBatcher.java:424] : 
    insert 
    into

    group (name
    , description, parent_id) 
values
    (?, ?, ?)
Hibernate: 
    insert 
    into

    group (name
    , description, parent_id) 
values
    (?, ?, ?)
2011-06-08 11:20:11,105 DEBUG [AbstractBatcher.java:507] : preparing statement
2011-06-08 11:20:11,116 DEBUG [AbstractEntityPersister.java:1987] : Dehydrating entity: [com.joonts.domain.Group#<null>]
2011-06-08 11:20:11,116 DEBUG [NullableType.java:133] : binding 'RealmUserGroup' to parameter: 1
2011-06-08 11:20:11,117 DEBUG [NullableType.java:133] : binding 'Base group' to parameter: 2
2011-06-08 11:20:11,117 DEBUG [NullableType.java:126] : binding null to parameter: 3
2011-06-08 11:20:11,118 DEBUG [AbstractBatcher.java:397] : about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2011-06-08 11:20:11,118 DEBUG [AbstractBatcher.java:556] : closing statement
2011-06-08 11:20:11,120 DEBUG [JDBCExceptionReporter.java:69] : could not insert: [com.joonts.domain.Group] [insert into group (name, description, parent_id) values (?, ?, ?)]
java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group (name, description, parent_id) values ('RealmUserGroup', 'Base group', nul' at line 1
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2975)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1600)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1695)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:3026)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1137)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1368)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1283)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1268)
        at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:73)
        at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:33)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2153)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2633)
        at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:51)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
        at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
        at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
        at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
        at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:315)
        at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:283)
        at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:238)
        at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
        at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:678)
        at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:662)
        at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:666)
        at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227)
        ....
2011-06-08 11:20:11,135 WARN  [JDBCExceptionReporter.java:77] : SQL Error: 1064, SQLState: 42000
2011-06-08 11:20:11,135 ERROR [JDBCExceptionReporter.java:78] : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group (name, description, parent_id) values ('RealmUserGroup', 'Base group        

在网页中,我收到此异常报告

java.lang.NullPointerException
    com.joonts.dao.impl.BaseJpaDao.save(BaseJpaDao.java:121)
    com.joonts.service.impl.GroupManagerImpl.saveGroup(GroupManagerImpl.java:21)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    $Proxy43.saveGroup(Unknown Source)
    com.joonts.action.ConfirmSignupAction.confirm(ConfirmSignupAction.java:118)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)

它没有使它工作,也不知道我做错了什么。 感谢您的帮助,并为长篇文章感到抱歉。

0 个答案:

没有答案