簡體   English   中英

JPA 不將外鍵保存到@OneToMany 關系

[英]JPA not saving foreign key to @OneToMany relation

我正在使用 Spring 和 Hibernate 作為 JPA 提供程序,並試圖獲取 @OneToMany(具有多個電話號碼的聯系人)以將外鍵保存在電話號碼表中。 從我的表格中,我得到一個聯系人 object,其中包含電話(號碼)列表。 Contact 得到正確的持久化(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;
    }
}

希望我得到了上面所有的相關位,否則請告訴我。

您必須自己管理 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;

  ...
}

回復 Cletus 的回答。 我會說在 id 字段以及所有序列內容上都有@column注釋很重要。 使用的參數的mappedBy的替代@OneToMany注釋是使用@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);
    }
}

如果 Contact-Phone 關系是單向的,你也可以用mappedBy @JoinColumn(name = "contact_id")替換@OneToMany注解中的@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)

我不認為addPhone方法是必要的,你只需要在電話對象中設置聯系人:

phone.setContact(contact);

如果您希望您的關系單向,即只能從聯系人導航到電話,則需要添加

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

在您的父實體上的@OneToMany下。

nullable = false IS VITAL如果您希望休眠在子表上填充 fk

試試這個示例:

@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;
}

在 JPA 這對我有幫助

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM