簡體   English   中英

JPA ManyToMany - findById 中的空列表

[英]JPA ManyToMany - empty list in findById

在我的 Spring 引導項目中,我有一個實體 class 用戶

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "applicationusers")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    [...]

    @Singular
    @ManyToMany(
        cascade = {
            CascadeType.PERSIST,
            CascadeType.MERGE
        },
        fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    @JoinTable(
        name = "applicationusers_roles",
        joinColumns = { @JoinColumn(name = "applicationuser_id") },
        inverseJoinColumns = { @JoinColumn(name = "role_id") }
    )
    private Set<Role> roles;
}

和第二個實體 class 角色

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    @Length(min = 3, max = 15)
    private String name;

    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "roles")
    @Fetch(value = FetchMode.SUBSELECT)
    @Singular
    private Set<User> applicationUsers;
}

在我的一項測試中,我嘗試像這樣將帶有用戶的角色存儲到存儲庫中

@Test
public void createRoleWithUsers() {
    User newUser = User.builder()
        .name("name")
        .password("1234567")
        .email("hello@world.net")
        .enabled(true)
        .build();
    User savedUser = userRepository.save(newUser);
    Set<User> users = new HashSet<>();
    users.add(savedUser);
    Role role = Role.builder()
        .name("TestRole")
        .applicationUsers(users)
        .build();
    Role createdRole = roleRepository.save(role);
    Role foundRole = roleRepository.findRoleById(createdRole.getId()).get();
    [...]
}

調試此代碼后,我發現createdRole已按預期設置用戶,但foundRole沒有。

createdRole 有用戶,foundRole 沒有用戶

我怎樣才能獲得foundRole中的用戶呢?

如果您需要存儲庫代碼,請告訴我 - 這是一個非常簡單的界面,所以我跳過了它。

簡化響應,閱讀精美手冊: 6.3.10。 配置 Fetch- 和 LoadGraphs

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "applicationusers")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Singular
    @ManyToMany
    private Set<Role> roles;
}

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToMany(mappedBy = "roles")
    @Singular
    private Set<User> applicationUsers;
}

該手冊規定:

public interface RoleRepository extends JpaRepository<Role, Long>{
    @Query("select r from Role r where r.id = :id")
    @EntityGraph(attributePaths = {"applicationUsers"})
    Role findByIdFetchUsers(@Param("id") Long id);
}

第二個System.out.println會給你一個org.hibernate.LazyInitializationException

@Override
public void run(String... args) throws Exception {
    User u = save();
    Role r2 = roleRepository.findByIdFetchUsers(u.getId());
    System.out.println("R: " + r2 + " : " + r2.getApplicationUsers());
    Role r1 = roleRepository.findById(u.getId()).get();
    System.out.println("R: " + r1 + " : " + r1.getApplicationUsers());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM