首页 > 解决方案 > JPA EntityManager 创建本机查询不返回外键数据

问题描述

我有两个实体,TableA 和 TableB,它们之间有一个多对多的映射。当我尝试使用 createNativeQuery 选择所有 table_b 时,我能够获取所有 table_b 的数据,但我无法引用 table_a 的任何数据。

table_a 实体

@Entity
@Table(name = "table_a")
public class TableA implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "data1")
    private String data1;

    @Column(name = "data2")
    private String data2;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(
            name = "a_b_mapping",
            joinColumns = @JoinColumn(name = "a_id"),
            inverseJoinColumns = @JoinColumn(name = "b_id"))
    private List<TableB> bItems;

    // getters/setters
    public List<TableB> getBItems() {
        if (bItems == null) { bItems = new ArrayList<>(); }

        return bItems;
    }

    public void setBItems(List<TableB> bItems) {
        this.bItems = bItems;
    }
}

table_b 实体

@Entity
@Table(name = "table_b")
public class TableB implements Serializable { 

    @Id
    @Column(name = "id")
    private Integer id;

    @ManyToMany(mappedBy = "bItems")
    private List<TableA> aItems;

    // Getters/Setters

    public List<TableA> getAItems() {
        if (aItems == null) { aItems = new ArrayList<>(); }

        return aItems;
    }

    public void setAItems(List<TableA> aItems) {
        this.aItems = aItems;
    }

}

注意:我在插入之前为 TableB 手动设置 id

处理器:

@Component
public class ProcessorDAO {

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;

    @Transactional
    public void process() {

        EntityManager em = entityManagerFactory.createEntityManager();
        EntityTransaction entityTransaction = em.getTransaction();

        try {
            entityTransaction.begin();

            Query q = em.createNativeQuery("SELECT * FROM table_b", TableB.class);
            List<TableB> tableBItems = q.getResultList();

            for (TableB item : tableBItems) {
                // Always 0 here?
                item.getAItems().size();
            }

            entityTransaction.commit();
        } catch (RuntimeException e) {
            if (entityTransaction.isActive()) {
                entityTransaction.rollback();
            }
            throw e;
        } finally {
            em.close();
        }
    }
}

如果我使用 TableB 存储库中的 findAll,我可以获取 AItems,但我试图让它仅与实体管理器一起使用,但不确定有什么区别。

标签: javaspring-bootjpa

解决方案


在您的情况下,外键实际上在表 A 中,仅选择表 B,无法获得关联。您需要加入到本机 sql 中的表 A。Select * from tableB Join tableA .....


推荐阅读