I'm trying to do a very simple delete operation, but somehow it doesn't work since I updated the DAOs to JpaRepository. Basically it's this:
A a = aRepository.findOne(id);
a.setSomeField("someNewString");
List<B> bList = a.getBs();
bList.clear();
aRepository.saveAndFlush(a);
The field get's updated as expected, but the bList
stays unchanged. I've even tried:
A a = aRepository.findOne(id);
a.setSomeField("someNewString");
List<B> bList = a.getBs();
for(B b : bList) {
bRepository.delete(b);
}
bRepository.flush();
bList.clear();
aRepository.saveAndFlush(a);
Still the same...
Class A looks like this:
@Entity
@Table(name = "A")
public class A implements Serializable {
private static final long serialVersionUID = -1286451120913657028L;
@Column(name = "id", length = 16, nullable = false, updatable = false)
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Basic(fetch = FetchType.EAGER)
@Id
protected UUID id;
@OneToMany(mappedBy = "a", fetch = FetchType.EAGER)
@Cascade({ CascadeType.ALL })
List<B> bList;
// getter + setter
}
What am I doing wrong?!
Class B:
@Entity
@Table(name = "B")
public class B implements Serializable {
@Column(name = "id", length = 16, nullable = false, updatable = false)
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Basic(fetch = FetchType.EAGER)
@Id
protected UUID id;
@ManyToOne(optional = false)
@JoinColumns({ @JoinColumn(name = "A_id", referencedColumnName = "id", nullable = false) })
@Valid
A a;
// setter + getter
}
Setters and getters are all just as simple as possbile:
public List<B> getBList() {
return bList;
}
public void setBList(List<B> bList) {
this.bList = bList;
}
Some more information:
Update the A.bList
property as follows:
public class A {
@OneToMany(mappedBy = "a", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
List<B> bList;
}
The orphanRemoval = true
annotation attribute will tell the underlying JPA implementation to delete B records which don't have any parent left.
Also, Since the B
side manages the association, you should clear its a
attribute when breaking the relationship. To make this easier to read and to remove the burden of such implementation details from the caller, you should introduce management methods in A
:
public class A {
public void clearBList() {
for (B b : bList) {
b.releaseA();
}
bList.clear();
}
}
public class B {
void releaseA() {
this.a = null;
}
}
You should avoid exposing collections directly and instead return an immutable version of it to prevent clients to the A class of modifying the collection directly without the A class knowing it. A
manages the B
list, so it should have full control over it!
public class A {
public List<B> getBList() {
return Collections.unmodifiableList(bList);
}
}
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With