English 中文(简体)
Boo Springt Data JPA Bidirectal Relations - Foreign Key Is Null
原标题:Spring Boot Data JPA Bidirectional Relationship - Foreign Key Is Null

我一直在就英雄和别.进行午餐会。 下面是Character级,由Superhero级延长:

@Data
@NoArgsConstructor
@Entity
@Table(name = "characters")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Superhero.class, name = "superhero"),
        @JsonSubTypes.Type(value = Villain.class, name = "villain")})
public abstract class Character {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Integer id;
    private String firstName;
    private String lastName;
    @Transient
    private String fullName;
    @Convert(converter = GenderConverter.class)
    private Gender gender;
    @Column(nullable = false)
    private String alias;
    @Convert(converter = StatusConverter.class)
    private Status status;
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;
    private String originStory;
    @Convert(converter = UniverseConverter.class)
    private Universe universe;

    public Character(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Character(String firstName, String lastName, String alias) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.alias = alias;
    }

    public String getFullName() {
        return firstName + " " + lastName;
    }
}

接着是Team,可以由多个英雄或别,组成,但只有一支英雄或别villa才能与一个团队联系:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "teams")
public class Team {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    @OneToMany(mappedBy = "team", cascade = CascadeType.ALL)
    private List<Character> characters;
    @Convert(converter = StatusConverter.class)
    private Status status;
}

在这里,我如何尝试启动,这些实体正在存放:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    /** Disable before running Tests! */
    @Bean
    public CommandLineRunner commandLineRunner(CharacterRepository characterRepository,
                                               TeamRepository teamRepository) {
        return args -> {
            // Initilaizing
            Superhero ironMan = new Superhero("Tony", "Stark", "Iron Man");
            Superhero thor = new Superhero("Thor", "Odinson", "God of Thunder");
            Team avengers = Team.builder().name("Avengers").status(DISBANDED).build();

            // Setting attributes
            ironMan.setGender(MALE); thor.setGender(MALE);
            ironMan.setUniverse(MCU); thor.setUniverse(MCU);
            ironMan.setStatus(DECEASED); thor.setStatus(ALIVE);

            // Saving to repositories
            characterRepository.saveAll(List.of(ironMan, thor));
            teamRepository.save(avengers);

            // Trying to assign foreign keys
            avengers.setCharacters(List.of(ironMan, thor));
            ironMan.setTeam(avengers);
            thor.setTeam(avengers);
        };
    }
}

The result in postgres looks like this:

demo2=# SELECT * FROM teams;
 id |   name   |  status
----+----------+-----------
  1 | Avengers | Disbanded
(1 row)


demo2=# SELECT * FROM superheroes;
 id | team_id |     alias      | first_name | gender | last_name | origin_story |  status  | universe
----+---------+----------------+------------+--------+-----------+--------------+----------+----------
  1 |         | Iron Man       | Tony       | Male   | Stark     |              | Deceased | MCU
  2 |         | God of Thunder | Thor       | Male   | Odinson   |              | Alive    | MCU
(2 rows)

如你看见<代码>team_id,作为两种英雄的外国钥匙是空的。 我尝试在<条码>上添加<条码>参考/代码>,在“编码”上添加“JoinColumn说明,添加机体类型、计算数据,然后确定属性,但既无帮助。

最佳回答

我想像我这样错失了秩序:

Firstly, I should have saved the team instance (not necessarily with characters attribute instantiated). Secondly, I should have assigned team attribute to player instances before saving them in the repository. Thirdly, After the first and second steps, I should have saved players in the repository.

因此,修改后的案文认为:

    @Bean
    public CommandLineRunner commandLineRunner(CharacterRepository characterRepository,
                                               TeamRepository teamRepository) {
        return args -> {
            // Initializing
            Superhero ironMan = new Superhero("Tony", "Stark", "Iron Man");
            Superhero thor = new Superhero("Thor", "Odinson", "God of Thunder");
            Team avengers = Team.builder().name("Avengers").status(DISBANDED).build();

            // Setting attributes
            ironMan.setGender(MALE); thor.setGender(MALE);
            ironMan.setUniverse(MCU); thor.setUniverse(MCU);
            ironMan.setStatus(DECEASED); thor.setStatus(ALIVE);

            // Step 1
            teamRepository.save(avengers);

            // Step 2
            ironMan.setTeam(avengers);
            thor.setTeam(avengers);

            // Step 3
            characterRepository.saveAll(List.of(ironMan, thor));

            // Trying to assign foreign keys
            avengers.setCharacters(List.of(ironMan, thor));
        };
    }
问题回答

我常常认为,在双向关系中采用帮助方法是有益的。 例如,在小组实体中,我要补充以下内容:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "teams")
public class Team {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    @OneToMany(mappedBy = "team", cascade = CascadeType.ALL)
    private List<Character> characters;
    @Convert(converter = StatusConverter.class)
    private Status status;

    // Helper Method
    public void addCharacter(Character character){
      characters.add(character);
      character.setTeam(this);
    }
   // You can have a similar method for adding many characters at once
}

之后,指挥线的操作人员改变如下:

@Bean
    public CommandLineRunner commandLineRunner(CharacterRepository characterRepository,
                                               TeamRepository teamRepository) {
        return args -> {
            // Initilaizing
            Superhero ironMan = new Superhero("Tony", "Stark", "Iron Man");
            Superhero thor = new Superhero("Thor", "Odinson", "God of Thunder");
            Team avengers = Team.builder().name("Avengers").status(DISBANDED).characters(new ArrayList<>()).build();

            // Setting attributes
            ironMan.setGender(MALE); thor.setGender(MALE);
            ironMan.setUniverse(MCU); thor.setUniverse(MCU);
            ironMan.setStatus(DECEASED); thor.setStatus(ALIVE);

            // Saving to repositories
            characterRepository.saveAll(List.of(ironMan, thor));
            

            // Trying to assign foreign keys
            avengers.addCharacter(ironMan);
            avengers.addCharacter(thor);
            teamRepository.save(avengers);
        };
    }




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...