Внешний ключ обновляется как ноль - PullRequest
1 голос
/ 10 октября 2019

Я пытаюсь реализовать двунаправленную связь с использованием аннотаций @OneToMany и @ManyToOne JPA. Мой внешний ключ обновляется как NULL, что неверно. Мне нужно немного информации для решения этой проблемы.

Я создал класс User и CardInfo. Я пытаюсь добавить отношения, где пользователь может иметь более одной карты. Когда я пытаюсь сохранить в базе данных, внешний ключ вставляется как ноль.

@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. Пожалуйста, поправьте меня, если понимание неверно.

1 Ответ

1 голос
/ 12 октября 2019

Хотя 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);
    }

}

Приведенный выше код обеспечивает синхронизацию обеих сторон отношения (т. Е. Если пользовательдобавляет карту к своим платежным реквизитам, затем информация о карте «принадлежит» пользователю).

Наконец, хотя это и не имеет прямого отношения к вашей проблеме, я бы посоветовал установить связь между CardInfo иUser обязательный и соответствующий ему столбец соединения NOT NULL, чтобы запросы были должным образом оптимизированы, и CardInfo не могло существовать в базе данных без связи с владельцем User:

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name="user_id", nullable = false)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...