java - 多对多额外列 Spring JPA

标签 java spring jpa spring-boot

已经过去了一个星期,我正在为一个问题而苦苦挣扎,似乎我找不到任何答案。

我有这样的结构: Database Structure

专辑型号:

@Entity
@Table(name = DatabaseConstants.ALBUM_TABLE_NAME)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Album {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @Column(nullable = false)
    private int imageVersion = 1;

    @Column(length = 255)
    private String description;

    @Column(nullable = false)
    private boolean single = false;

    @Column(nullable = false)
    private Long createdAt;

    @Column(nullable = true)
    private Long deletedAt;

    // Relations

    @OneToMany(fetch = FetchType.LAZY)
    private List<AlbumView> albumViews;

    // Getters and Setters
}

AlbumView 模型:

@Entity
@Table(name = DatabaseConstants.ALBUM_VIEW_RELATION_TABLE_NAME)
public class AlbumView {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private boolean bigger;

    @Column(nullable = false)
    private int position;

    @Column(nullable = false)
    private Long createdAt;

    @Column(nullable = true)
    private Long deletedAt;

    // Relations

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "album_id")
    private Album album;

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "view_id")
    private View view;

    // Getters and Setters    
}

查看模型:

@Entity
@Table(name = DatabaseConstants.VIEW_TABLE_NAME)
public class View {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Long createdAt;

    @Column(nullable = true)
    private Long deletedAt;

    // Relations

    @OneToMany(fetch = FetchType.LAZY)
    private List<AlbumView> albumViewList;

    // Getters and Setters
}

我需要按 View 搜索相册列表。我需要的查询类似于(使用来自 Spring JPA 的 @Query 注释):

SELECT a, av.bigger, av.position FROM Album a, AlbumView av WHERE av.view.id = ?    

但我无法映射这两个值(更大、位置),因为它们不在 Album 模型中。我需要建立一个响应,例如:

[
    {
        id: 1,
        name: 'Test Album',
        imageVersion: 1,
        description: 'Description one',
        single: true,
        bigger: true,
        position: 1
    },
    {
        id: 2,
        name: 'Test Album 2',
        imageVersion: 1,
        description: 'Description two',
        single: true,
        bigger: false,
        position: 2
    }
]

据我所知,我不能使用 @Transient 在这里帮助我(因为显然 JPA 忽略它并且 @Query 不填充这些属性) 而且我不知道其他方法。 谢谢。

编辑 1

我在 Spring JPA 的 Repository 类中使用以下代码尝试了@bonifacio 的建议:

@Query("SELECT av.album.id, av.album.name, av.album.imageVersion, av.bigger, av.position FROM AlbumView av WHERE av.view.id = ?1")
List<AlbumView> findByViewId(Long id);

但我得到了以下响应:

[
    [
        1,
        "Test Best Hits",
        1,
        true,
        1
    ]
]

值正是这样,但它正在考虑这是一个数组,而不是像它假设的那样的对象..

最佳答案

执行此操作的一种方法是更改​​查询以选择 AlbumView 实体,该实体包含 AlbumView 和 Album 实体中的所有所需字段,并且还可以在查询的 WHERE 子句中使用 View 实体。

在这种情况下,一种可能的解决方案是使用以下查询:

SELECT av FROM AlbumView av WHERE av.view.id = ?1

此外,我想指出,在您的第一个示例中,您尝试每行获取三个不同的对象,如下例所示:

SELECT a, av.bigger, av.position FROM Album a, AlbumView av WHERE av.view.id = ? 

它不起作用的原因是因为当您选择多个列(或对象)时,您不会自动在一行中获取所需的字段,因为 Hibernate 会将结果转换为对象数组(对象[ ]) 对于查询结果的每一行。因此,除非您真的需要在一行中选择多个对象,否则始终建议您在每个 SELECT 中只返回一个字段或实体。

关于java - 多对多额外列 Spring JPA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34134447/

相关文章:

java - 使用 Java 在 Android Studio 上使用 WebRTC

java - SSE 发射器 : Manage timeouts and complete()

java - 尝试将数据输入数据库时​​出现 InvalidStateException

spring - 如何在同一个 Spring Data JPA 保存请求中级联创建和存储引用?

java - 为什么 JPA 双重插入子实体?

jpa - 选择实体包含列表的位置,该列表是另一个列表的子集

java - 在 Android 中叠加图像

java - com.google 无法解析为类型

java - 禁用 JDBC 连接上的 keystore

spring - fmt formatNumber 类型 ="currency"显示 "¤"而不是实际的货币符号