Каскадные действия JPA для однозначных отношений - PullRequest
0 голосов
/ 25 мая 2020

У меня есть следующий вопрос относительно отношений один к одному (и я предполагаю, что один ко многим тоже):

Предположим, у меня есть следующие таблицы:

create table user (
    id bigint auto_increment primary key,
    username varchar(100) not null,
    constraint UK_username unique (username)
);
create table user_details(
    userId bigint not null primary key,
    firstName varchar(100) null,
    lastName  varchar(100) null,
    constraint user_details_user_id_fk foreign key (userId) references user (id)
);

As вы можете видеть, что две таблицы имеют один и тот же первичный ключ. Теперь я создал следующие объекты:

import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

@Data
@Entity
public class User {

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

    @NotBlank
    @Column(unique = true)
    @Size(min = 1, max = 100)
    private String username;

    @MapsId
    //without this I get an exception on this table not having a column named: userDetails_userId
    @JoinColumn(name = "id")
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private UserDetails userDetails;
}
import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.Size;

@Data
@Entity(name = "user_details")
public class UserDetails {

    @Id
    private Long userId;

    @Column(unique = true)
    @Size(min = 1, max = 100)
    private String firstName;

    @Column(unique = true)
    @Size(min = 1, max = 100)
    private String lastName;

}

Когда я пытаюсь сохранить нового пользователя, у меня есть объект пользователя со всеми сгенерированными значениями, кроме user.id и userDetail.userId. . Когда я пытаюсь сохранить это, я получаю следующую ошибку:

"org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before calling save(): com.app.entity.UserDetails; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.app.UserDetails

Обратите внимание, что для сохранения объекта User я создал этот интерфейс:

public interface UserRepository extends JpaRepository<User, Long> { }

, и я использую метод сохранения предоставляется.

    ...

    @Autowired
    private UserRepository userRepository;

    ...

    public ResponseEntity<HttpStatus> addUser(User user) {
        userRepository.save(user);
        return ResponseEntity.ok(HttpStatus.OK);
    }

объект перед сохранением выглядит следующим образом:

User(id=null, username=test, userDetails=UserDetails(userId=null, firstName=test, lastName=test))

Мне было интересно, могу ли я просто сохранить пользовательский объект и каскадно передать сгенерированный ключ в userDetail.

Следует ли мне использовать другой подход для сохранения или что-то не так с моими сущностями?

1 Ответ

0 голосов
/ 27 мая 2020

Вы сделали что-то не в том направлении.

@Data
@Entity
public class User {

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

    @NotBlank
    @Column(unique = true)
    @Size(min = 1, max = 100)
    private String username;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
    private UserDetails userDetails;
}

@Data
@Entity(name = "user_details")
public class UserDetails {

    @Id
    private Long userId;

    @Column(unique = true)
    @Size(min = 1, max = 100)
    private String firstName;

    @Column(unique = true)
    @Size(min = 1, max = 100)
    private String lastName;

    @MapsId
    @JoinColumn(name = "USERID")
    @OneToOne(fetch = FetchType.LAZY)
    private User user;
}

При этом вы можете просто установить ссылку userDetail.user, и JPA сохранит пользователя, назначит ему идентификатор и будет использовать его для заполнения значения UserDetail.id для вас - в вашей модели и в базе данных.

Вы должны поддерживать ссылку user.userDetail, но она имеет меньшее значение для данных строки базы данных и больше по причинам согласованности объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...