【问题标题】:Many-To-Many extra columns Spring JPA多对多额外列 Spring JPA
【发布时间】:2015-12-07 13:14:11
【问题描述】:

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

我有这样的结构:

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
    ]
]

值就是这样,但它认为这是一个数组,而不是像它应该的那样的对象..

【问题讨论】:

  • 不能直接选择 AlbumView 实体吗? SELECT av.album.id, av.album.name, av.album.imageVersion, av.bigger, av.position FROM AlbumView av WHERE av.view.id = ? ?
  • @Bonifacio 有点用,但不完全,我用结果更新了问题
  • @augustoccesar 发生这种情况的原因是因为在我的示例和您的示例中,选择的不是实体,而是一个数组,如果您选择多个列,结果将始终是一个数组,这是默认的 Hibernate 行为。在这种情况下,您应该只选择您想要的对象实体:SELECT av FROM AlbumView av WHERE av.view.id = ?1
  • @Bonifacio 成功了!谢谢!但只是出于好奇,因为您似乎掌握了它:D 如果我想过滤表中的某些列以不带所有对象,有没有办法在查询中执行此操作(无需将其转换为数组)?
  • @augustoccesar 我发现那里有 JsonInclude 注释,这让我假设这里涉及到 Web 服务。你真正想解决什么?您从数据库中获取哪些信息,或者您在 Web 服务中公开了哪些信息?如果是后者,我宁愿专注于让 Web 服务技术为您完成工作,而不是 JPA。

标签: java spring jpa spring-boot


【解决方案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 中只返回一个字段或实体。

【讨论】:

    猜你喜欢
    • 2018-07-09
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2014-07-13
    • 2019-02-06
    • 1970-01-01
    • 2020-03-03
    相关资源
    最近更新 更多