JPA外键是空的

时间:2012-03-28 18:32:09

标签: java jpa

我正在开发一个Web应用程序,我正在使用JSF和JPA(EclipseLink)。我有表storystory_translate,其映射如下:

@Entity
@Table(name = "story")
public class Story{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Integer id;
private String title;
private String description;
@OneToMany(mappedBy = "story", cascade=CascadeType.ALL)
private List<StoryTranslate> translateList;

    //getters and setters
 }

@Entity
@Table(name = "story_translate")
public class StoryTranslate{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Integer id;
@Column(name="STORY_ID")
private Integer storyId;
    @ManyToOne
@JoinColumn(name="story_id", referencedColumnName="id", updatable=false, insertable=false)
private Story story;

   //some other fields, getters and setters
}

ManagedBean中,我正在执行以下操作:

 StoryTranslate translate = new StoryTranslate(null, sessionController.getEntity().getId(), getAuthUser().getId(), language, 
                    title, description, new Date(), false);
 EntityTransaction transaction = TransactionSingleton.getActiveInstance();
            Story story = storyService.read(sessionController.getEntity().getId());
            if (story != null){
                if (story.getTranslateList() == null){
                    story.setTranslateList(new ArrayList<StoryTranslate>());
                }
                story.getTranslateList().add(translate);
                translate.setStory(story);
            }
            transaction.commit();

当我尝试创建新的StoryTranslate时,我得到DatabaseException,说story_id不能为空。

之前我曾经管理过关系,但我从未见过这个错误。

问题出在哪里?

编辑:我很抱歉,但我已经忘记了映射的另一部分(必须是睡眠不足)。

1 个答案:

答案 0 :(得分:3)

问题是,您在storyId列的StoryTranslate类中声明了STORY_ID属性,但在添加新的StoryTranslate时,您没有设置任何值它的storyId属性,我相信STORY_ID列有一个NOT NULL约束,这就是为什么你得到异常,说story_id不能为空。

在提交事务之前设置storyId实例的StoryTranslate属性后,应解决该问题。

但是,您将STORY_ID列映射到storyId类的两个不同属性(storyStoryTranslate)很奇怪。实际上,您不需要声明storyId属性,因为可以从story实例检索此值。我建议您将StoryTranslate的映射更改为以下内容,您的代码应该可以正常工作而无需任何更改。

@Entity
@Table(name = "story_translate")
public class StoryTranslate{
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE)
   private Integer id;

   @ManyToOne
   @JoinColumn(name="story_id")
   private Story story;

   //some other fields, getters and setters
}