由JPA ManyToMany生成的空连接表 [英] Empty Join Table resulting from JPA ManyToMany

查看:151
本文介绍了由JPA ManyToMany生成的空连接表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,其中我尝试使用Hibernate作为我的JPA提供程序在两个实体之间实现ManyToMany关系。

I have an application in which I am trying to implement ManyToMany relation between 2 entities using Hibernate as my JPA provider.

我正在尝试的示例是一个uni-方向一,其中一个相机可以有多个镜头和Lense可以适合多个相机。

The example I am trying is an uni-directional one, wherein a Camera can have multiple Lenses and Lense can fit into multiple Cameras.

以下是我的实体类...(只是粘贴相关部分)

Following is my entity class...(Just pasting the relevant part of it)

相机:

@Entity
@Table(name = "CAMERAS")
public class Camera implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "CAM_ID", nullable = false)
    private Long camId;

    @Column(name="CAMERA_BRAND")
    private String cameraBrand;

    @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER)
    @JoinTable(name="CAMERA_LENS",joinColumns=@JoinColumn(name="CAM_ID"),inverseJoinColumns=@JoinColumn(name="LENS_ID"))
        private Set<Lens> lenses = new HashSet<Lens>();

    ...
}

镜头:

@Entity
@Table(name = "LENSES")
public class Lens implements Serializable {        
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "LENS_ID", nullable = false)
    private Long lensId;

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

    ...
}

在测试用例中,我尝试像这样坚持Camera实例......

In the test-case, I try to persist the Camera instance like this...

@Test
public void test_saveCameraLenseManyToMany() {
    Camera cam = new Camera();
    cam.setCameraBrand("Nikon");
    Set<Camera> cameras = new HashSet<Camera>();
    cameras.add(cam);

    Set<Lens> lenses = new HashSet<Lens>();
    Lens lens1 = new Lens();
    lens1.setName("WideAngle");
    lenses.add(lens1);

    cam.setLenses(lenses);

    // concreteDAO.saveLens(lens1);
    concreteDAO.saveCamera(cam);
}

持久性成功发生,并且Hibernate没有抛出错误/异常。但是,与期望相反,JoinTable中不会创建行(在本例中为CAMERA_LENS)。仅在每个镜头和相机表中创建一行,因此不符合ManyToMany的目的。但是,为连接表生成了DDL,并且它也被创建,但只是它没有任何记录。

The persistence happens successfully, and there is no error/exception thrown by Hibernate. However, contrary to expectation, a row is not created in the JoinTable (CAMERA_LENS in this case). A row is created in each of Lens and Camera tables only, thereby not serving the purpose of ManyToMany. However, the DDL is generated for the join table and it is created as well, but just that it does not have any records.

任何帮助或指针都将非常感激。

Any assistance or pointers would be much appreciated.

推荐答案

我发现了问题。这有点奇怪。我使用的DAO类具有类级别注释:

I found the problem. It is a bit weird. The DAO class that I was using had a class level annotation of:

@Transactional(readOnly=true)

生成的sql是

Hibernate: insert into CAMERAS (CAMERA_BRAND) values (?)
Hibernate: insert into LENSES (LENS_NAME) values (?)
Hibernate: insert into LENSES (LENS_NAME) values (?)

仍然保存了2个实体,但没有将数据保存或插入到连接表中。

And still it saved the 2 entities, but did not save or insert data into the join table.

我添加方法级别注释的那一刻:

The moment I added a method level annotation of :

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)

一切都很好,数据确实插入了加入表。在这种情况下生成的新SQL是......

everything turned out to be fine, and data was indeed inserted into the join table. The new SQLs generated in this case was...

Hibernate: insert into CAMERAS (CAMERA_BRAND) values (?)
Hibernate: insert into LENSES (LENS_NAME) values (?)
Hibernate: insert into LENSES (LENS_NAME) values (?)

Hibernate: insert into CAMERAS_LENSES (CAM_ID, LENS_ID) values (?, ?)
Hibernate: insert into CAMERAS_LENSES (CAM_ID, LENS_ID) values (?, ?)



<有点奇怪的是,没有交易传播策略将数据保存到2个表中,但是一旦给出了传播策略,一切都证明是好的。

Kinda weird still that no transaction propogation strategy saved data into 2 tables, but once the propogation strategy was given, everything turned out to be fine.

另一个有趣的观察是我尝试将propogation策略作为MANDATORY放在方法级别(检查是否存在导致第一个和错误的情况的事务),但是该方法引发了一个异常,表明没有事务存在,仍然将数据保存到2桌。

Another interesting observation is that I tried putting the propogation strategy as MANDATORY at the method level (to check if there existed a Transaction which led to the first and faulty case), however the method threw an exception indicating that no transaction existed, still the data was saved into the 2 tables.

希望能帮助更进一步的人......

Hope that helps someone further on...

这篇关于由JPA ManyToMany生成的空连接表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆