spring 实体未定义IdClass

1l5u6lss  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(109)

我有两个实体,一个是用户,第二个是外部帐户。
下面是mysql的create代码:

CREATE TABLE `User` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `firstName` VARCHAR(100) NOT NULL COLLATE 'utf8_unicode_ci',
    `lastName` VARCHAR(100) NOT NULL COLLATE 'utf8_unicode_ci',
    `date_add` DATETIME NOT NULL DEFAULT current_timestamp(),
    PRIMARY KEY (`id`) USING BTREE
)
ENGINE=InnoDB
AUTO_INCREMENT=15
;

CREATE TABLE `ExternalAccount` (
    `user_id` INT(10) UNSIGNED NOT NULL,
    `id_external_account` VARCHAR(100) NOT NULL COLLATE 'utf8_unicode_ci',
    `date_add` DATETIME NOT NULL DEFAULT current_timestamp(),
    PRIMARY KEY (`user_id`) USING BTREE,
    INDEX `id_external_account` (`id_external_account`) USING BTREE,
    CONSTRAINT `FK_user` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

这里我的3个生成实体:

package com.namirial.raws.timestamp.persistence.entities;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;

import java.time.LocalDateTime;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@IdClass(ExternalAccountId.class)
@Table(name = "ExternalAccount", schema = "my_db")
public class ExternalAccount {

    @Id
    @OneToOne
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    private User user;

    @CreatedDate
    @Column(name = "date_add", nullable = false)
    private LocalDateTime dateAdd = LocalDateTime.now();

    @Column(name = "id_external_account", nullable = false, length = 100, unique = true)
    private String idExternalAccount;
public class ExternalAccountId implements Serializable {

    User user;
}
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "User", schema = "my_db")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "first_name", length = 100, nullable = false)
    private String firstName;

    @Column(name = "last_name", length = 100, nullable = false)
    private String lastName;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private ExternalAccount externalAccount;

}

但是当我在创建一个User(使用UserRepo)后尝试保存一个externalAccount时,我得到一个Entity Does not define an IdClass。我正在使用Java 17与Webflux和JpaRepository

public class UserBusinessServices {

public void createUser(){
 User user = new User();
user.setFirstName("JOHN");
user.setLastName("MOT");
user.setExternalAccount(new ExternalAccount(...));
userRepo.save(user);
}

}

为什么会出现这个错误?奇怪的是,我找不到任何这样的数据库结构的例子,我找到的唯一解决方案是在ExternalAccount上使用复合主键,在userid上使用唯一索引。数据库结构是否与框架不兼容?谢谢你的忠告。
将值保存在db上并了解数据库结构是否错误

yfjy0ee7

yfjy0ee71#

1.您不需要@IdClass,因为您没有复合主键。因此,您只需要2个实体
1.使用@MapsId,因为ExternalAccount表与User表(id)共享其主键(user_id)。

  1. UserId应存在于具有@Id的ExternalAccount实体中
  2. ExternalAccount是一对一关系的所有者方。所以用户应该有mappedBy。
    这应该是实体:
package com.namirial.raws.timestamp.persistence.entities;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;

import java.time.LocalDateTime;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "ExternalAccount", schema = "my_db")
public class ExternalAccount {

    @Id
    private Integer userId;

    @OneToOne
    @MapsId("userId")
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    private User user;

    @CreatedDate
    @Column(name = "date_add", nullable = false)
    private LocalDateTime dateAdd = LocalDateTime.now();

    @Column(name = "id_external_account", nullable = false, length = 100, unique = true)
    private String idExternalAccount;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "User", schema = "my_db")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "first_name", length = 100, nullable = false)
    private String firstName;

    @Column(name = "last_name", length = 100, nullable = false)
    private String lastName;

    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private ExternalAccount externalAccount;

}

您可以在这里阅读有关共享主键的信息:https://thorben-janssen.com/hibernate-tips-same-primary-key-one-to-one-association/
你可以在这里阅读关于业主关系的一面:What is the "owning side" in an ORM mapping?

相关问题