Как я могу создать родительский объект только один раз, когда в спящем режиме создаются несколько дочерних объектов? - PullRequest
1 голос
/ 27 февраля 2020

У меня есть один класс пользователя и один класс заметки, определенные следующим образом:

@Entity
@Table(name = "notes")
public class Note {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column
    private String title;
    @Column
    private String content;
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

// getters and setters
}


@Entity
@Table(name="users")
public class User {
    @Id
    @Column
    private int id;
    @Column
    private String name;
    @Column
    private String userName;

 //getters and setters
}

Я пытаюсь создать «Заметку», и я хочу добиться того, чтобы в качестве части моей полезной нагрузки запроса, Я передам свои данные пользователя с идентификатором, как показано ниже:

[{
    "title": "Mynote",
    "content": "This is another note",
    "user": {
        "id": 4,
        "name": "user_1",
        "userName": "S"
    }
}]

Я хочу, чтобы, если "Пользователь" уже был там, он не должен обновлять таблицу пользователей новой записью, а если пользователь с данной Идентификатор не существует, он должен создать новый и связать его с заметками.

Для этого я использовал @ManyToOne(cascade = CascadeType.ALL), выше private User user поля в классе «Заметки». Он работает для одного запроса, но для следующего запроса выдает

java.sql.SQLIntegrityConstraintViolationException: 
   Duplicate entry '5' for key 'PRIMARY'

Это ожидается, поскольку он пытается вставить одну и ту же строку дважды.

Можно ли добиться этого с помощью некоторой аннотации весной или od Я должен обработать это в своем собственном коде следующим образом: при создании заметки я должен проверить, существует ли пользователь, и если он не существует, то создать новую, а затем сохранить заметку.

(По сути, это то, чего я хочу добиться, используя hibernate / spring-data-jpa, если есть некоторая поддержка).

1 Ответ

0 голосов
/ 27 февраля 2020

Для получения более подробной технической информации, пожалуйста, взгляните на ссылку, предоставленную @Chinthaka Dinadasa под вашим вопросом.

Для быстрого и более простого решения, подумайте об этом с другой стороны. Давайте добавим заметки пользователю и сохраним этого пользователя (не заметку).

Пользовательская сущность

@Entity
@Table(name = "users")
public class User {

    @Id
    private Integer id;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) // !!! add "cascade" 
    private List<Note> notes = new ArrayList<Note>();

Заметная сущность

@Entity
@Table(name = "note_table")
public class Note {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

теперь, если вы попытаетесь дважды вызвать следующий метод в некотором @Service, у вас будет один пользователь и 2 примечания для этого пользователя:

@Service
public class MyService {
    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void acceptNewNote() {
        User user = new User();
        user.setId(0L);
        Note note = new Note();
        user.setNotes(Arrays.asList(note));

        userRepository.save(user);

где UserRepository is:

public interface UserRepository extends CrudRepository<User, Integer>
...