Hibernate一对多级联保存空指针异常

时间:2012-12-13 14:54:18

标签: hibernate nullpointerexception save one-to-many cascade

我有以下两个类中所述的一对多关系

    @Entity
    @Table(name="version_mst")
    public class Version {

    private Long   id;
    private String versionName;
    private String releaseName;
    private Set<VersionReleaseComponents> versionReleaseComponents; 

    @Id
    @GeneratedValue
    @Column(name="id")
    public Long  getId() {
        return id;
    }
    public void setId(Long  id) {
        this.id = id;
    }

    @Column(name="versionName")
    public String getVersionName() {
        return versionName;
    }
    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }

    @Column(name="releaseName")
    public String getReleaseName() {
        return releaseName;
    }
    public void setReleaseName(String releaseName) {
        this.releaseName = releaseName;
    }

    @OneToMany(mappedBy="version",cascade = { javax.persistence.CascadeType.ALL },fetch = FetchType.EAGER,targetEntity=VersionReleaseComponents.class)
    public Set<VersionReleaseComponents> getVersionReleaseComponents() {
        return versionReleaseComponents;
    }
    public void setVersionReleaseComponents(
            Set<VersionReleaseComponents> versionReleaseComponents) {
        this.versionReleaseComponents = versionReleaseComponents;
    }

      }       

一个版本有许多VersionReleaseComponents

     @Entity
     @Table(name="version_release_components")
     public class VersionReleaseComponents {

    private Long id;

    @Id
    @GeneratedValue
    @Column(name="id")
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "versionId")
    private Long versionId;
    public Long getVersionId() {
        return versionId;
    }
    public void setVersionId(Long versionId) {
        this.versionId = versionId;
    }
    private Version version;
    private String componentName;
    private String versionNumber;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="versionId", referencedColumnName="id", insertable = false, updatable = false)
    public Version getVersion() {
        return version;
    }
    public void setVersion(Version version) {
        this.version = version;
    }

    @Column(name="componentName")
    public String getComponentName() {
        return componentName;
    }
    public void setComponentName(String componentName) {
        this.componentName = componentName;
    }

    @Column(name="versionNumber")
    public String getVersionNumber() {
        return versionNumber;
    }
    public void setVersionNumber(String versionNumber) {
        this.versionNumber = versionNumber;
    }

        }     

当我尝试执行以下

        Version v = new Version();
        v.setReleaseName("RN1");
        v.setVersionName("VName1");

        VersionReleaseComponents vrc = new VersionReleaseComponents();
        vrc.setComponentName("cn1");
        vrc.setVersionNumber("VNum1");
        vrc.setVersion(v);

        v.getVersionReleaseComponents().add(vrc); // null pointer error on here
        session.saveOrUpdate(v);

获取set时我得到一个空指针异常。请指导我。

创建查询如下

      CREATE TABLE `version_mst` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      `versionName` varchar(20) NOT NULL,
      `releaseName` varchar(20) NOT NULL,
      `last_modified_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`ID`),
      UNIQUE KEY `VERSION_MAPPING_MST_UNIQUE` (`versionName`,`releaseName`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

    CREATE TABLE `version_release_components` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      `versionId` int(10) NOT NULL ,
      `componentName` varchar(20) NOT NULL,
      `versionNumber` varchar(20) NOT NULL,
      `last_modified_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`ID`),
      CONSTRAINT `FK_VERSION` FOREIGN KEY (`versionId`) REFERENCES `version_mst` (`id`),
      UNIQUE KEY `VERSION_RELEASE_UNIQUE` (`componentName`,`versionNumber`)
    ) ENGINE=InnoDB   DEFAULT CHARSET=latin1;

5 个答案:

答案 0 :(得分:2)

Version中,您尚未实例化:

private Set<VersionReleaseComponents> versionReleaseComponents; 

因此,您要将VersionReleaseComponents添加到未初始化的Set

修复,设置:

private Set<VersionReleaseComponents> versionReleaseComponents = new HashSet<VersionReleaseComponents>(); 

或您需要的Set

答案 1 :(得分:0)

尝试替换

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="versionId", referencedColumnName="id", insertable = false, updatable = false)
public Version getVersion() {
  return version;
}

为此:

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="versionReleaseComponents")
   public Version getVersion() {
      return version;
    }

并使用@ user1393563的推荐:

private Set<VersionReleaseComponents> versionReleaseComponents = new HashSet<VersionReleaseComponents>();

问候。

答案 2 :(得分:0)

更改了以下内容: 删除了VersionReleaseComponents中的声明

     @Column(name = "versionId")
    private Long versionId;
    public Long getVersionId() {
        return versionId;
    }
    public void setVersionId(Long versionId) {
        this.versionId = versionId;
    }

将VersionReleaseComponents声明更改为

 @JoinColumn(name="versionId")

和版本声明是

@OneToMany(mappedBy="id",cascade = { javax.persistence.CascadeType.ALL },fetch =  FetchType.LAZY)

以上修改有效。 虽然它不是解决方案的一部分,但由于其他原因,我已更改为FetchType.LAZY。

答案 3 :(得分:0)

我认为你正在尝试将一个项目添加到Set为NULL。

试试这个:

    Version v = new Version();
    v.setReleaseName("RN1");
    v.setVersionName("VName1");

    VersionReleaseComponents vrc = new VersionReleaseComponents();
    vrc.setComponentName("cn1");
    vrc.setVersionNumber("VNum1");
    vrc.setVersion(v);

    Set<VersionReleaseComponents> vrcs = new HashSet<VersionReleaseComponents>();
    vrcs.add(vrc);
    v.setVersionReleaseComponents(vrcs);

    session.saveOrUpdate(v);

答案 4 :(得分:0)

最有可能是因为您尚未初始化Set变量。在构造函数或字段声明中对其进行初始化。

在运行您的代码时,我遇到了相同的异常,然后在将变量初始化为以下内容后,它就起作用了:

private Set<VersionReleaseComponents> versionReleaseComponents = new HashSet<>();