Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA中的双向关系_Java_Jpa - Fatal编程技术网

Java JPA中的双向关系

Java JPA中的双向关系,java,jpa,Java,Jpa,我有两个实体类,User和MyCharacter。用户有一个MyCharacter列表,每个MyCharacter都有一个对用户(所有者)的引用。我想实现的是,我对这两个关系使用相同的联接表,这意味着在MyCharacter中找到的所有者关系将自动使用与from User=>MyCharacter相同的联接表。这意味着MyCharacter中的getOwner()方法应该可以工作,而无需在某个时候显式调用setOwner(user) 为了进一步澄清这一点,下面是我的单元测试,它当前失败(最后一次

我有两个实体类,User和MyCharacter。用户有一个MyCharacter列表,每个MyCharacter都有一个对用户(所有者)的引用。我想实现的是,我对这两个关系使用相同的联接表,这意味着在MyCharacter中找到的所有者关系将自动使用与from User=>MyCharacter相同的联接表。这意味着MyCharacter中的getOwner()方法应该可以工作,而无需在某个时候显式调用setOwner(user)

为了进一步澄清这一点,下面是我的单元测试,它当前失败(最后一次断言失败)


@试验
public void testtwowayrelations(){
用户=新用户();
MyCharacter=新的MyCharacter();
列表字符=新的ArrayList();
字符。添加(字符);
user.setCharacters(字符);
门面。商店(用户);
assertNotNull(character.getId());
character=facade.find(MyCharacter.class,character.getId());
assertNotNull(character.getOwner());
}
下面列出了我的实体类


@Entity
@Table(name = "myuser")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

    @OneToMany(cascade = { CascadeType.PERSIST })
    protected List<MyCharacter> characters;

    public User() {

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public List<MyCharacter> getCharacters() {
        return characters;
    }

    public void setCharacters(List<MyCharacter> characters) {
        this.characters = characters;
    }

}


@Entity
public class MyCharacter{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

    @ManyToOne
    @JoinTable(name = "myuser_mycharacter", joinColumns = @JoinColumn(name = "characters_id"), inverseJoinColumns = { @JoinColumn(name = "user_id") })
    protected User owner;

    public MyCharacter() {

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public User getOwner() {
        return owner;
    }

    public void setOwner(User owner) {
        this.owner = owner;
    }
}

@实体
@表(name=“myuser”)
公共类用户{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
保护长id;
@OneToMany(cascade={CascadeType.PERSIST})
受保护的列表字符;
公共用户(){
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共列表getCharacters(){
返回字符;
}
公共void集合字符(列表字符){
这个。字符=字符;
}
}
@实体
公共类MyCharacter{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
保护长id;
@许多酮
@JoinTable(name=“myuser\u mycharacter”,joinColumns=@JoinColumn(name=“characters\u id”),inverseJoinColumns={@JoinColumn(name=“user\u id”)})
受保护的用户所有者;
公共字符(){
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共用户getOwner(){
归还所有人;
}
公共无效集合所有者(用户所有者){
this.owner=所有者;
}
}
来自Oracle,它解释了如何映射此类关系

当您在Java中使用此功能时,根据您的JPA框架,您需要将
MyCharacter
添加到
User
中的列表中,并在
MyCharacter
中设置
User
字段或仅设置其中一个字段(因为框架将为您管理另一端)。我建议编写一个小测试来找出什么是有效的(并且您应该为您使用对象的所有方式编写测试用例)


当从数据库加载对象时,您不需要这样做,因为所有框架都能正确处理这种情况。

这就是我们在项目中使用jpa连接两个实体的方式:

    @Entity
    @Table(name = "Period")
    public class Period implements Serializable {
      private List<Delay> delays = new ArrayList<Delay>();

      @OneToMany(mappedBy="period") //name of the field in joined entity
      public List<Delay> getDelays() {
        return delays;
      }
    }

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

    private Period period;

    @ManyToOne
    @JoinColumn(name = "PERIODID")
    public Period getPeriod() {
       return period;
    }   
}
@实体
@表(name=“期间”)
公共类周期实现可序列化{
私有列表延迟=新的ArrayList();
@OneToMany(mappedBy=“period”)//关联实体中字段的名称
公共列表getDelays(){
返回延迟;
}
}
@实体
@表(name=“延迟”)
公共类延迟实现可序列化{
私人时期;
@许多酮
@JoinColumn(name=“PERIODID”)
公共期间getPeriod(){
重现期;
}   
}

我不确定是否正确理解了您的问题,但您可以尝试在MyCharacter.owner上设置mappedBy:

@ManyToOne(mappedBy="characters")
@ManyToOne(mappedBy="characters")