I am currently stuck on an issue of updating a parent entity field and getting the update to cascade to all its children's fields.
Here is an example of what I am trying to accomplish:
User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false, columnDefinition = "TINYINT(1) default false")
private Boolean archived = Boolean.FALSE;
@OneToMany(mappedBy = "user")
private Set<Invoice> invoices = new HashSet<Invoice>();
// Setters & Getters
}
Invoice.java
@Entity
public class Invoice{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false, columnDefinition = "TINYINT(1) default false")
private Boolean archived = Boolean.FALSE;
@ManyToOne(mappedBy = "invoices")
@JoinColumn(nullable = false)
private User user;
// Setters & Getters
}
When I update the archived value to true
. I want all the invoices to also be updated to true
as well.
I.E
public Boolean archiveUserById(Integer id) {
User user= entity_manager.find(User.class, id);
Boolean result = false;
if(auction != null) {
// This should cascade to all the invoices as well and update their archived fields to true as well
user.setArchived(true);
try {
entity_manager.getTransaction().begin();
entity_manager.merge(auction);
entity_manager.getTransaction().commit();
result = true;
} catch(Exception e) {
e.printStackTrace();
}
}
return result;
}
I've tried using cascade = CascadeType.PERSIST
and @JoinTable(....)
with all the referenced columns, but they are still failing to update the fields correctly.
To clarify is there a way to update a child's field through its parents' update with a Cascade effect?
Thank-you for the help.
To clarify my question, I am trying to add a constraint cascade effect when a field on the parent entity is updated to reflect on the child entity's same field. I am trying to avoid any logic within the Entity itself. Is there a way to do this through annotations only?
Something to the same effect as this:
ALTER TABLE `child` ADD CONSTRAINT `childs-archived-mirrors-parent`
FOREIGN KEY (`archived`, `parentId`)
REFERENCES `parent`(`archived`, `id`)
ON DELETE RESTRICT ON UPDATE CASCADE;
Thanks for all your help.
I ended up finding a solution. I created a custom foreign key definition that will cascade any update on the archived field to its child entities.
Below is how I accomplished that.
@Entity
public class Invoice{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false, columnDefinition = "TINYINT(1) default false")
private Boolean archived = Boolean.FALSE;
@ManyToOne(mappedBy = "invoices")
@JoinColumn(nullable = false, foreignKey = @ForeignKey(foreignKeyDefinition = "FOREIGN KEY (archived, user_id) REFERENCES user(archived, id) ON DELETE RESTRICT ON UPDATE CASCADE"))
private User user;
// Setters & Getters
}