Empty Join Table as a result of JPA ManyToMany

I have an application in which I am trying to implement the ManyToMany relationship between two objects using Hibernate as my JPA provider.

The example I'm trying to do is unidirectional, in which a camera can have multiple lenses and lenses that can be inserted into multiple cameras.

Below is my entity class ... (just pasting the appropriate part)

Camera:

@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>(); ... } 

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; ... } 

In a test case, I'm trying to save a camera instance in a way 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); } 

Persistence is successful and there is no error / exception caused by Hibernate. However, contrary to expectations, the line is not created in JoinTable (CAMERA_LENS in this case). A line is created only in each of the lens and camera tables, thereby not serving the purpose of ManyToMany. However, a DDL is created for the connection table, and it is also created, but it just has no records.

Any help or pointers would be greatly appreciated.

+6
java orm jpa many-to-many
source share
1 answer

I found a problem. It's a bit strange. The DAO class that I used had class-level annotation:

 @Transactional(readOnly=true) 

The generated sql was

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

And yet he saved 2 objects, but did not save and did not enter data into the connection table.

The moment I added the method level annotation:

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

everything turned out to be in order, and the data was indeed inserted into the connection table. The new SQL created 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 (?, ?) 

It is strange that no transaction proposition strategy saved data in 2 tables, but after the proposition strategy was given, everything turned out to be in order.

Another interesting point is that I tried to apply the distribution strategy as MANDATORY at the method level (to check if there was a transaction that led to the first and erroneous case), but the method threw an exception indicating that the transaction did not exist, nevertheless data was stored in 2 tables.

Hope someone helps ...

+5
source share

All Articles