java JPA未将外键保存到@OneToMany关系

zkure5ic  于 2023-01-24  发布在  Java
关注(0)|答案(7)|浏览(163)

我使用Spring和Hibernate作为JPA提供程序,并尝试获取@OneToMany(一个有很多电话号码的联系人)来保存电话号码表中的外键。从我的窗体中,我得到了一个联系人对象,它有一个电话号码列表(数字)。联系人已正确持久化(Hibernate从指定的序列中获取一个PK)。Phone(numbers)列表也使用正确的PK进行持久化,但是Contacts表中没有FK。

public class Contact implements Serializable {

    @OneToMany(mappedBy = "contactId", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    private List<Phone> phoneList;

}

public class Phone implements Serializable {

    @JoinColumn(name = "contact_id", referencedColumnName = "contact_id")
    @ManyToOne
    private Contact contactId;

}

@Repository("contactDao")
@Transactional(readOnly = true)
public class ContactDaoImpl implements ContactDao {

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void save(Contact c) {
        em.persist(c);
        em.flush();
    }
}

@Controller
public class ContactController {
    @RequestMapping(value = "/contact/new", method = RequestMethod.POST)
    public ModelAndView newContact(Contact c) {
        ModelAndView mv = new ModelAndView("contactForm");
        contactDao.save(c);
        mv.addObject("contact", c);
        return mv;
    }
}

希望我得到了上面所有的相关位,否则请让我知道。

0ve6wy6x

0ve6wy6x1#

您必须自己管理Java关系。对于这类事情,您需要类似以下的东西:

@Entity
public class Contact {
  @Id
  private Long id;

  @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "contact")
  private List<Phone> phoneNumbers;

  public void addPhone(PhoneNumber phone) {
     if (phone != null) {
        if (phoneNumbers == null) {
            phoneNumbers = new ArrayList<Phone>();          
        }
        phoneNumbers.add(phone);
        phone.setContact(this);
     }
  }

  ...
}

@Entity
public class Phone {
  @Id
  private Long id;

  @ManyToOne
  private Contact contact;

  ...
}
mspsb9vt

mspsb9vt2#

对于Cletus的回答,我认为在id字段上加上@column注解以及所有的序列信息是很重要的,除了使用@OneToMany注解的mappedBy参数之外,还有一种方法是使用@JoinColumn注解。
顺便说一句,你需要看看addPhone的实现,它可能是这样的。

public void addPhone(PhoneNumber phone) {
    if (phone == null) {
        return;
    } else {
        if (phoneNumbers == null) {
            phoneNumbers = new ArrayList<Phone>();
        }
        phoneNumbers.add(phone);
        phone.setContact(this);
    }
}
lsmd5eda

lsmd5eda3#

如果Contact-Phone关系是单向的,您还可以将@OneToMany注解中的mappedBy替换为@JoinColumn(name = "contact_id")

@Entity
public class Contact {
  @Id
  private Long id;

  @OneToMany(cascade = CascadeType.PERSIST)
  @JoinColumn(name = "contact_id")
  private List<Phone> phoneNumbers;

  // normal getter/setter
  ...
}

@Entity
public class PhoneNumber {
  @Id
  private Long id;

  ...
}

JPA @OneToMany -> Parent - Child Reference (Foreign Key)中相似

9fkzdhlc

9fkzdhlc4#

我不认为addPhone方法是必要的,您只需要在phone对象中设置联系人:

phone.setContact(contact);
kxe2p93d

kxe2p93d5#

如果您希望您的关系是单向的,即只能从联系人导航到电话,则需要添加

@JoinColumn(name = "contact_id", nullable = false)

在父实体的@OneToMany下。
nullable = falseIS VITAL(如果希望hib填充子表上的fk)

pn9klfpd

pn9klfpd6#

尝试以下示例:

@Entity
public class Contact {
    @Id
    private Long id;

    @JoinColumn(name = "contactId")
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Phone> phones;
}

@Entity
public class Phone {
    @Id
    private Long id;
    private Long contactId;
}
vyswwuz2

vyswwuz27#

在JPA中,这帮助了我

contact.getPhoneList().forEach(pl -> pl.setContact(contact));
contactRepository.save(contact);

相关问题