OneToOne外键保存问题

时间:2013-04-23 16:09:20

标签: java hibernate jpa

   @Entity
    @Table(name = "applicant")
    public class Applicant implements Serializable {

        private static final long serialVersionUID = -8634638904962909584L;

        // Primary id required by Hibernate
        @Id
        @GeneratedValue(strategy=IDENTITY)
        @Column(name = "applicant_id", nullable=false, unique=true)
            private Long applicantId; // Unique id for each applicant

        @OneToOne(cascade = CascadeType.ALL)
        @Fetch(value = FetchMode.SELECT)
        @JoinColumn(name = "applicant_id", referencedColumnName= "applicant_id")
        private DS1350 ds1350;


        public Applicant () {

        }

    }

    @Entity
    @Table(name = "ds_1350")

    public class DS1350 implements Serializable {
        private static final long serialVersionUID = -7370747595057569296L;

        // Primary id required by Hibernate
        @Id
        @GeneratedValue(strategy=IDENTITY)
        @Column(name = "ds_1350_id", nullable=false, unique=true)
        private Long ds1350Id;

        @Column(name = "applicant_id", unique=true, nullable=false)
    //    @GeneratedValue(generator="gen")
    //  @GenericGenerator(name = "gen", strategy = "foreign", parameters = @Parameter(name = "property", value = "applicant"))
        private Long applicantId; // Unique id for each applicant

        @Column(name = "ds1350_no", length = 50)
        private String ds1350Number;

    }

   public class ApplicantDaoTest {
        @Autowired
        private ApplicantDao applicantDao;

        private Applicant applicant;
        private DS1350 ds1350 = new DS1350();

        @BeforeClass
        public static void beforeClass() {
        }


        @AfterClass
        public static void afterClass() {
        }


        @Before
        public void setup() {
            this.initApplicant();
        }

        @After
        public void teardown() {
        }

        private void initApplicant() {
            applicant = new Applicant();

            applicant.setFirstName("John");

            Calendar calendar = Calendar.getInstance();
            applicant.setDob(calendar);

            applicant.setSsn("123456789");
            applicant.setCreatedBy("JUNIT");
            applicant.setCreatedDate(Calendar.getInstance());
            applicant.setModifiedBy("JUnit");
            applicant.setModifiedDate(Calendar.getInstance());

            this.initDS1350();

        }


        private void initDS1350 () {        
            ds1350.setDs1350Number("ds1350Number");
            ds1350.setCreatedBy("JUNIT");
            ds1350.setCreatedDate(Calendar.getInstance());  

            applicant.setDs1350(ds1350);
        }

        @Test
        public void testSaveApplicant() {
            Long applicantId = applicantDao.saveApplicant(applicant);
            applicant = applicantDao.getApplicantByPrimaryKey(applicantId);
            assertTrue("ds1350Number".equals(applicant.getDs1350().getDs1350Number()));
        }
    }

这是ds1350和申请者类的代码。我使用hibernate session save()来保存申请人对象中包含ds1350的申请人。我有一个完美的OneToMany,但这个OneToOne无法正常工作。 applicant.getDs1350()抛出NullPointerException,因为外键(ds1350中的applicant_id)保存为null,applicantDao.getApplicantByPrimaryKey(applicantId)无法获取ds1350对象。

1 个答案:

答案 0 :(得分:1)

摆脱“@Fetch(value = FetchMode.SELECT)”。你告诉它在你的OneToOne注释中急切地获取它,然后告诉它用@Fetch注释懒得获取。

此外,请确保ds1350字段上的连接列具有引用的正确FK字段(如果申请人中的字段未被称为id)。

@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "applicant_id", referencedColumnName= "applicant_id")
private DS1350 ds1350; 

我最初错过的另一点是你正在使用

   @GeneratedValue(strategy=IDENTITY)

引用documentation: “表示持久性提供程序必须使用数据库标识列为实体分配主键。”

如果您在创建链接时没有手动分配想法,则不会保留ID。使用@GeneratedValue(strategy = AUTO)将告诉数据库它需要为您的子类生成ID(DS1350)。这是一个修复,但可能不是你想要的。

此外,根据您的更新,您在连接列中引用了错误的外键,并且ds1350与您的申请人之间的关联看起来很可疑,请尝试以下操作:

 //in applicant
    @OneToOne(cascade = CascadeType.ALL)
    @Fetch(value = FetchMode.SELECT)
    @JoinColumn(name = "ds1350_id", referencedColumnName= "applicant_id")
    private DS1350 ds1350;

   //in ds1350
   @OneToOne(mappedBy="applicant", cascade=CascadeType.ALL)
   private Applicant applicant; // Unique id for each applicant

我没有测试过。