Reputation: 11
I am doing an exercise on the CRUD operations in a many-to-many relationship having attributes in the relationship table.
I am attaching my entities and I hope you can help me.
The error mentioned above occurs when I go to ask for the list of elements on the zetautente and zetamessaggio tables.
The same error occurs even when I go to ask for a single element of one of the two above mentioned tables ..
@Entity(name = "ZetaMessaggio")
@Table(name="zetamessaggio")
public class ZetaMessaggio implements Serializable {
private static final long serialVersionUID = -2387302703708194311L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "zetamessaggio_seq")
@SequenceGenerator(name = "zetamessaggio_seq",sequenceName = "zetamessaggio_seq",allocationSize = 1)
private Long id;
@Column(name = "titolo")
private String titolo;
@Column(name = "testo")
private String testo;
@OneToMany(
mappedBy = "zetaMessaggio",
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JsonManagedReference(value="zetaMessaggio")
private List<ZetaMessaggioUtente> zetaUtente = new ArrayList<ZetaMessaggioUtente>();
public ZetaMessaggio() {
}
public ZetaMessaggio(String titolo, String testo)
{
this.titolo = titolo;
this.testo = testo;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitolo() {
return titolo;
}
public void setTitolo(String titolo) {
this.titolo = titolo;
}
public String getTesto() {
return testo;
}
public void setTesto(String testo) {
this.testo = testo;
}
public List<ZetaMessaggioUtente> getZetaUtente() {
return zetaUtente;
}
public void setZetaUtente(List<ZetaMessaggioUtente> zetaUtenti) {
this.zetaUtente = zetaUtenti;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
ZetaMessaggio other = (ZetaMessaggio) o;
return Objects.equals(new Long(this.id), new Long(other.id))
&& Objects.equals(this.titolo, other.titolo)
&& Objects.equals(this.testo, other.testo);
}
@Override
public int hashCode() {
return Objects.hash( new Long(this.id)
, this.testo
, this.titolo
);
}
}
@Entity(name = "ZetaMessaggioUtente")
@Table(name = "zetamessaggioutente")
public class ZetaMessaggioUtente implements Serializable {
private static final long serialVersionUID = 4060038267093084727L;
@EmbeddedId
private ZetaMessaggioUtenteId id;
@Column(name="data")
private String data;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("idMessaggio")
@JoinColumn(name = "idMessaggio")
@JsonBackReference(value = "zetaMessaggio")
private ZetaMessaggio zetaMessaggio;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("idUtente")
@JoinColumn(name = "idUtente")
@JsonBackReference(value = "zetaUtente")
private ZetaUtente zetaUtente;
private ZetaMessaggioUtente() {}
public ZetaMessaggioUtente(ZetaMessaggioUtenteId id)
{
this.id = id;
}
public ZetaMessaggioUtente(ZetaMessaggio messaggio, ZetaUtente utente)
{
this.zetaMessaggio = messaggio;
this.zetaUtente = utente;
this.id = new ZetaMessaggioUtenteId(messaggio.getId(), utente.getId());
}
public ZetaMessaggioUtenteId getId() {
return id;
}
public void setId(ZetaMessaggioUtenteId id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public ZetaMessaggio getZetaMessaggio() {
return zetaMessaggio;
}
public void setZetaMessaggio(ZetaMessaggio zetaMessaggio) {
this.zetaMessaggio = zetaMessaggio;
}
public ZetaUtente getZetaUtente() {
return zetaUtente;
}
public void setZetaUtente(ZetaUtente zetaUtente) {
this.zetaUtente = zetaUtente;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
{
return false;
}
ZetaMessaggioUtente other = (ZetaMessaggioUtente) o;
return Objects.equals(zetaMessaggio, other.zetaMessaggio)
&& Objects.equals(zetaUtente, other.zetaUtente)
;
}
@Override
public int hashCode()
{
return Objects.hash(zetaMessaggio, zetaUtente);
}
}
@Embeddable
public class ZetaMessaggioUtenteId implements Serializable {
private static final long serialVersionUID = -7372159721389421199L;
@Column(name = "idMessaggio")
private Long idMessaggio;
@Column(name = "idUtente")
private Long idUtente;
private ZetaMessaggioUtenteId(){}
public ZetaMessaggioUtenteId(Long idMessaggio,Long idUtente){
setIdMessaggio(idMessaggio);
setIdUtente(idUtente);
}
public Long getIdMessaggio() {
return idMessaggio;
}
public void setIdMessaggio(Long idMessaggio) {
this.idMessaggio = idMessaggio;
}
public Long getIdUtente() {
return idUtente;
}
public void setIdUtente(Long idUtente) {
this.idUtente = idUtente;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass())
{
return false;
}
ZetaMessaggioUtenteId other = (ZetaMessaggioUtenteId) o;
return Objects.equals(new Long(this.idMessaggio), new Long(other.idMessaggio)) &&
Objects.equals(new Long(this.idUtente), new Long(other.idUtente))
;
}
@Override
public int hashCode()
{
return Objects.hash( new Long(this.idMessaggio)
, new Long(this.idUtente)
);
}
}
@Entity(name = "ZetaUtenti")
@Table(name = "zetautenti",uniqueConstraints = {@UniqueConstraint(columnNames = {"Id"})})
public class ZetaUtente implements Serializable {
private static final long serialVersionUID = -5338956772143977741L;
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "zetautenti_seq")
@SequenceGenerator(name = "zetautenti_seq",sequenceName = "zetautenti_seq",allocationSize = 1)
private Long id;
@Column(name = "nome")
private String nome;
@Column(name = "cognome")
private String cognome;
@OneToMany(
mappedBy = "zetaUtente",
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JsonManagedReference(value="zetaUtente")
private List<ZetaMessaggioUtente> zetaMessaggio = new ArrayList<ZetaMessaggioUtente>();
public ZetaUtente() {
}
public ZetaUtente(String nome, String cognome)
{
this.nome = nome;
this.cognome = cognome;
}
public Long getId() {
return id;
}
public void setId(Long id) {
id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public List<ZetaMessaggioUtente> getZetaMessaggio() {
return zetaMessaggio;
}
public void setZetaMessaggio(List<ZetaMessaggioUtente> zetaMessaggi) {
this.zetaMessaggio = zetaMessaggi;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
ZetaUtente other = (ZetaUtente) o;
return Objects.equals(new Long(this.id), new Long(other.id))
&& Objects.equals(this.nome, other.nome)
&& Objects.equals(this.cognome, other.cognome);
}
@Override
public int hashCode() {
return Objects.hash( new Long(this.id)
, this.nome
, this.cognome
);
}
}
Upvotes: 1
Views: 108
Reputation: 821
By default @OneToMany
and @ManyToMany
relationships are lazy, so you need to handle receiving lazy data.
There are plenty of advices on the internet, it's very strange that you are asking this question, but if very quickly, you have few ways for getting lazy collection:
Antipatterns: OpenSessionInView
and enable_lazy_load_no_trans
Most popular way: to use @Transactional
annotation (auto attach object to session pool) or manual with start transaction, get collection, close transactional
Similar way: Hibernate.initialize(<get collection method>)
Manual way: use own SQL request with "JOIN FETCH ...
"
Alternative way: to use @Fetch(FetchMode.SUBSELECT)
(cannot say anything)
Not proper way (but the fastest temporary solution): to use FetchMode.EAGER
for collection
Upvotes: 1
Reputation: 11146
Collections are lazily loaded by default, if you are not aware of this thing then you can check the link Lazy loading of collection.
To make your code working you need to add following in OneToMany :
fetch = FetchType.EAGER
Upvotes: 0