A
A
acwartz2021-01-26 23:02:44
Java
acwartz, 2021-01-26 23:02:44

How to attach a list of other entities to an entity and then work with them and with the list?

Hey!

There is a certificate (Certificate), it can have many tags (Tag).

Actually, I would like to understand how I can now work with its tags through the class of a specific Certificate? Get all his tags, change one/several? Add/remove new, etc.
Methods for this kind of started, in fact, before jpa there were lists so that RestController at least issued something and it was possible to write / read something at run-time.
How to stick the tag repository there - I'll never know.

repository here

base fields

....
@MappedSuperclass
public abstract class CommonFields implements Serializable {
  
  private static final long serialVersionUID = 5618898539406697796L;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @JsonProperty("id")
  @Column(name = "id", nullable = false)
  private long id;

  @JsonProperty("name")
  @Column(name = "name", nullable = true)
  private String name;

  @JsonProperty("dateCreated")
  @Column(name = "dateCreated", nullable = false)
  private ZonedDateTime dateCreated;

  @JsonProperty("dateUpdated")
  @Column(name = "dateUpdated", nullable = false)
  private ZonedDateTime dateUpdated;

}
...



Certificate

package by.alex.certws.domain;

@JsonSerialize
@Entity
@Table(name = "certificates")
public class Certificate extends CommonFields {
  
  private static final long serialVersionUID = -3444580092047125843L;
  
  @JsonProperty("content")
  private String content;

  @JsonProperty("tags")
  @OneToMany(targetEntity=Tag.class, mappedBy="id",cascade=CascadeType.ALL, fetch = FetchType.LAZY)    
  private List<Tag> tags = new ArrayList<>();

  public Certificate() {
    super();
  }

  public Certificate(long certId, String certName) {
    super(certId, certName);
  }

  public Certificate(long certId, String certName, String content) {
    super(certId, certName);
    this.setContent(content);
  }

  public Certificate(long id, String name, String content, String[] tags) {
    super(id, name);
    this.setContent(content);
    for (String tag : tags) {
      addTag(tag);
    }
  }

  public String getContent() {
    return this.content;
  }

  public void setContent(String target) {
    this.content = target;
    this.UpdateNotify();
  }

  public List<Tag> getTags() {
    return this.tags;
  }

  public Optional<Tag> findTagByName(String name) {
    return this.tags.stream().filter(Objects::nonNull)
        .filter(t -> (Objects.nonNull(t.getName()) && t.getName().compareTo(name) == 0)).findAny();
  }

  public long addTag(String tagName) {
    Optional<Tag> match = this.findTagByName(tagName);
    if (match.isPresent()) {
      return match.get().getId();
      // throw new ETagExistsException();
    } else {
      return 0;
    }
  }

  public Boolean removeTag(String target) {
    Optional<Tag> match = this.findTagByName(target);
    if (match.isPresent()) {
      return this.tags.remove(match.get());
    } else {
      // TODO: MUST throw exception
      return false;
    }
  }

}



Tag

package by.alex.certws.domain;

....

@Entity
@Table(name = "tags")
public class Tag extends CommonFields {
  
  @JsonProperty("references")
  @OneToMany(targetEntity=Certificate.class, mappedBy="id",cascade=CascadeType.ALL, fetch = FetchType.LAZY)    
  private List<Certificate> refs = new ArrayList<>();
  
  private static final long serialVersionUID = -2535451222904563266L;

  public Tag() {
    super();
  }

  public Tag(long id, String name) {
    super(id, name);
  }
  
  List<Certificate> getReferences() {
    return this.refs;
  }

}



There are also interfaces
public interface CertificatesRepository extends PagingAndSortingRepository<Certificate, Long> {}
...
public interface TagsRepository extends PagingAndSortingRepository<Tag, Long> {}


It is assumed that in the tags table there may be a bunch of duplicates by name, i.e. 3 certificates can have the same "Java" tag or something like that.
I still don’t quite understand how and why, but usually I create tagsIDS for such a table with my hands where the Autokey connection will actually live, Certificate.id = Tag.id and now it’s not there.
but here everything is through .... automation / simplification and conversion of classes and properties to sql, etc.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Orkhan, 2021-01-27
@acwartz

Good afternoon!
First, based on your words:

There is a certificate (Certificate), it can have many tags (Tag).
It is assumed that in the tags table there may be a bunch of duplicates by name, i.e. 3 certificates can have the same "Java" tag or something like that.

I can assume that the OneToMany & ManyToOne relationship is not very suitable.
Here, look: one certificate can have several tags, but one tag can refer to different certificates. There is clearly a ManyToMany connection. https
://vladmihalcea.com/the-best-way-to-use-the-m...
https://www.baeldung.com/jpa-many-to-many
you can get a list of its tags, and from the tag side, you can get a list of certificates to which it belongs.
Otherwise, it turns out that there is a connection from the side of the tag and the OneToMany certificate, but at the same time List is used on both sides.
When using ManyToMany, a new table of the form will be created certificate_id | tag_idwhere you can store data. And correspondingly,
How to attach a list of other entities to an entity and then work with them and with the list?

This issue will resolve itself.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question