12

The jhipster doesn't support create many to many relationships with extra fields.

What is the best way to create many to many association with extra columns in jhispter? Should i create a two one-to-many relationship with extra fields?

Vítor Nóbrega
  • 1,219
  • 4
  • 26
  • 53
  • Your question is a tiny bit unclear. I assume your extra fields are in the join table. between A and B. Do you want to have a many-to-many-mapping between A and B and ignore the extra fields, or do you want to use them? – Antares42 Jan 29 '16 at 21:51
  • sorry. i updated my question. i need to create a many to many with extra columns but jhipster doesnt support it – Vítor Nóbrega Jan 29 '16 at 23:21
  • 3
    That doesn't answer my question. Many-to-many means there is a join table in your database. Is this where the extra columns are? If yes, then you will need to map the join table explicitly as its own entity. Table A -> JoinTable with extra fields -> Table B. This is not a limitation of jhipster. It is by definition impossible to access the fields in the join table using Many-to-many, becaue the whole point of many to many is not having to deal (not even seeing) the join table. – Antares42 Jan 30 '16 at 12:32

3 Answers3

12

Using JHipster Domain Language (JDL), a @ManytoMany holding extra properties (columns) can be easily achieved using an association entity and two ManyToOne relationships. See below:

entity Foo{
    ...
}

entity Bar{
    ...
}

entity FooBarAssociation{
    extraProperty1 String
    extraProperty2 String
    ...
}

relationship ManyToOne {
  FooBarAssociation{foo} to Foo{bars}
  FooBarAssociation{bar} to Bar{foos}
}
JesusIniesta
  • 10,412
  • 1
  • 35
  • 28
0

You will have to do it manually. this post describes how: https://hellokoding.com/jpa-many-to-many-extra-columns-relationship-mapping-example-with-spring-boot-maven-and-mysql/

In general, as @Antares42 said, you should create an entity for the Many-To-Many table like so:

first entity:

@Entity
public class Book{
private int id;
private String name;
private Set<BookPublisher> bookPublishers;

public Book() {
}

public Book(String name) {
    this.name = name;
    bookPublishers = new HashSet<>();
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<BookPublisher>   getBookPublishers() {
    return bookPublishers;
}

public void setBookPublishers(Set<BookPublisher> bookPublishers) {
    this.bookPublishers = bookPublishers;
}
}

secound entity:

@Entity
public class Publisher {
private int id;
private String name;
private Set<BookPublisher> bookPublishers;

public Publisher(){

}

public Publisher(String name){
    this.name = name;
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@OneToMany(mappedBy = "publisher")
public Set<BookPublisher> getBookPublishers() {
    return bookPublishers;
}

public void setBookPublishers(Set<BookPublisher> bookPublishers) {
    this.bookPublishers = bookPublishers;
}
}

Join table entity:

@Entity
@Table(name = "book_publisher")
public class BookPublisher implements Serializable{
private Book book;
private Publisher publisher;
private Date publishedDate;

@Id
@ManyToOne
@JoinColumn(name = "book_id")
public Book getBook() {
    return book;
}

public void setBook(Book book) {
    this.book = book;
}

@Id
@ManyToOne
@JoinColumn(name = "publisher_id")
public Publisher getPublisher() {
    return publisher;
}

public void setPublisher(Publisher publisher) {
    this.publisher = publisher;
}

@Column(name = "published_date")
public Date getPublishedDate() {
    return publishedDate;
}

public void setPublishedDate(Date publishedDate) {
    this.publishedDate = publishedDate;
}
}

This entity describes the relationship between Book and Publisher and the extra field is published_date

nave_eni
  • 51
  • 3
-1

Let's say you have entities like Movie, Rater and needs a join table Ratings. You can write a JDL script like the following:

entity Movie { title String}
entity Rater { name String}
entity Rating { value Integer} //the extra field

relationship ManyToMany {
   Rating{rater(name)} to Rater,
   Rating{movie(title)} to Movie
}

save it in file.jdl in the project folder, open cmd type

jhipster import-jdl file.jdl

and you have everything

aristotll
  • 8,694
  • 6
  • 33
  • 53
Mohamed Zaki
  • 164
  • 2
  • 11
  • 1
    Unfortunately, this is not delivering what is expected: one join table with a compose PK of Movie PK and Rater PK and a third column with the value of the rating. This will generate a manyToMany between Movie Rating and Rater Rating which is not correct. Please update your answer. – duderoot Nov 04 '18 at 18:56