3

I'm relatively new to Spring and JPA etc. I'm trying to create a many-to-many relationship between Tags and Customers (bi-directional)

I think I've got the relationship right. It all works well, except one problem. The Tag value is "Null" after it's saved to the database.

So what I'm doing is - adding a new List of Tags to the customer, then using the Cascade option to persist it when the customer is saved. I set a debug point before I call CustomerRepository.save(customer), and the tags all have values. After the save operation (on the customer repository) I observe two things - the Tags against the customer still aren't associated with an id, but in the database the tags are created but the values aren't stored in the column. So if I have 4 tags set against the customer, there will be 4 new rows in both the relationship table and the tag table, but the values will be null even though they're set correctly against the Tag object.

Also, if I call save against the tag repository directly before trying to save via the cascade, it saves the values and it all works (except for the transactionality aspects of it)...

Can anyone explain why the value column would be null when saving via the Cascade.persist option?

From Customer Class

@ManyToMany
    @JoinTable(
            name="customer_tags",
            joinColumns={@JoinColumn(name="customerId", referencedColumnName="id")},
            inverseJoinColumns={@JoinColumn(name="tagId", referencedColumnName="id")})
    @Cascade(value = CascadeType.PERSIST)
    private List<Tag> tags = new LinkedList<Tag>();

From Tag Class:

@ManyToMany(mappedBy = "tags")
private List<Customer> customers;

And my repository is this:

/**
 * The tag interface is used to retrieve, save and manage customer tags.
 */
public interface TagRepository extends JpaRepository<Tag, Long> {
    /**
     * Finds a list of tags
     * @return
     */
    public List<Tag> findByTag(String tag);

}
Richard G
  • 4,549
  • 10
  • 44
  • 86

2 Answers2

1

In fact, SpringData will use mostly merge when you call save so you'd better set the cascade to PERSIST and MERGE.

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name="address")
    private Address address;
wargre
  • 4,355
  • 1
  • 17
  • 34
0

I think the problem is that you're using hibernate dedicated method save() instead of persist(). I suggest you to delete @Cascade (which is for hibernate session object, not for entity manager) and use @ManyToMany(cascade = CascadeType.PERSIST) and it should work as you want.

energizer
  • 91
  • 6
  • I changed the annotation to the JPA one and it didn't have any effect. The save method is from the Spring JPA template and calls persist under the covers. – Richard G Aug 03 '14 at 08:50
  • try to change cascadeType to CascadeType.ALL – energizer Aug 03 '14 at 16:58
  • Changing to CascadeType.ALL seems to have worked. I'm not sure why it would be different though. I'll mark it as correct, but if you could leave a comment for why that would be great... – Richard G Aug 09 '14 at 15:52