多对多额外列Spring JPA

时间:2015-12-07 13:14:12

标签: java spring jpa spring-boot

已经过了一个星期,我正在努力解决问题,似乎我无法找到任何答案。

我有这个结构: Database Structure

Album型号:

@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    
}

View型号:

@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
}

我需要按视图搜索专辑列表。我需要的查询类似于(使用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
    ]
]

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

1 个答案:

答案 0 :(得分: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会将结果转换为Object数组(Object [ ])查询结果的每一行。因此,除非您确实需要在一行中选择多个对象,否则始终建议您在每个SELECT上只返回一个字段或实体。