我正在尝试使用@OneToMany和@ManyToOne JPA注释实现双向关系。我的外键正在更新为NULL,这是不正确的。我需要一些输入来解决此问题。

我已经创建了User和CardInfo类。我试图添加一种关系,其中用户可以拥有多个卡。当我尝试保留在数据库中时,将外键插入为null。

@Entity
@Table(name = "customer_info")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    //@GeneratedValue
    private String userId;
    private String userName;
    private Date dateOfBirth;
    private boolean primeMember;

    @OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST, orphanRemoval = true)
    private Set<CardInfo> paymentDetails;


@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name="card_info")
public class CardInfo implements Serializable {
    @Id
    private String cardNumber;
    @Id
    private String cardType; // Debit, Credit
    private String cardCategory; // Visa, mastercard
    private Date expiryDate;
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="user_id")
    @EqualsAndHashCode.Include private User user;



public class DAOImpl {
@Transactional
    public String addCustomer(User user) {
//        User _user=new User();
//        Set<CardInfo> cardData=new HashSet<>();
//
        String userId=String.valueOf(Instant.now().toEpochMilli());
        user.setUserId(userId);
Session session=sessionFactory.getCurrentSession();
session.persist(user);
return userId;
}


mysql> select * from card_info;
+----------+-------------+--------------+---------------------+---------+
| cardType | cardNumber  | cardCategory | expiryDate          | user_id |
+----------+-------------+--------------+---------------------+---------+
| CREDIT   | 74959454959 | VISA         | 2020-04-23 00:00:00 | NULL    |
+----------+-------------+--------------+---------------------+---------+
1 row in set (0.00 sec)


user_id列不应更新为NULL。如果理解不正确,请纠正我。

最佳答案

尽管Cascade.PERSIST确保CardInfo对象与它们的父对象User一起保留,但是应用程序或对象模型有责任维护关系[ 1]。

由于外键在CardInfo中,因此必须确保每个CardInfo都与要持久保存的User相关联。一种常见的模式是添加额外的逻辑来处理域对象中关系的双方,例如:

public class User {

    // fields, accessors and mutators

    public void addPaymentDetails(CardInfo cardInfo) {
        if (paymentDetails == null) {
            paymentDetails = new LinkedHashSet<>();
        }
        if (cardInfo.getUser() != this) {
            cardInfo.setUser(this);
        }
        paymentDetails.add(cardInfo);
    }

}


上面的代码可确保关系的双方保持同步(即,如果用户将卡添加到其支付详细信息中,则该卡信息将由用户“拥有”)。

最后,虽然与您的问题没有直接关系,但我的建议是使CardInfoUser及其各自的联接列NOT NULL之间的关系成为必需,以便正确优化查询,并且在查询中不能存在CardInfo数据库与其所属的User没有关联:

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name="user_id", nullable = false)

09-26 14:43