skip to Main Content

I am using Java, Spring and JPA and cannot get cascade deletion to work.

I have a class Tenant that looks like this

@Entity
@Validated
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TenantConstraints
public class Tenant {

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tenant_gen")
  @SequenceGenerator(name="tenant_gen", sequenceName="tenant_seq", allocationSize=1)
  @JsonProperty("id")
  private Long id = null;

  @JsonIgnore
  @OneToMany(mappedBy = "tenant", fetch = FetchType.EAGER)
  private List<DeploymentStep> deploymentSteps = new ArrayList();

  ...
}

My DeploymentStep class looks like this:

@Entity
@Validated
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DeploymentStep   {
  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "deployment_step_gen")
  @SequenceGenerator(name="deployment_step_gen", sequenceName="deployment_step_seq", allocationSize=1)
  @JsonProperty("id")
  private Long id = null;
 
  @ManyToOne(cascade = CascadeType.ALL)
  @JsonIgnore
  private Tenant tenant = null;

  ...
}

I have a repository class that looks like this

public interface TenantRepository extends JpaRepository<Tenant, Long> {
   ...
}

When I call the built-in delete method on this repository like so tenantRepository.delete(tenantId) and I have deployment steps for the particular tenant I’m deleting, the delete fails.

In my postgres database I have a cascade constraint set

ALTER TABLE public.deployment_step
  DROP CONSTRAINT tenant_fkey
, ADD  CONSTRAINT tenant_fkey FOREIGN KEY (tenant_id) REFERENCES public.tenant(id) ON DELETE CASCADE;

When I delete the tenant that has deployment steps using a database query manually, the tenant and all deploymentsteps get deleted without any issue.

What am I doing wrong in the code?

2

Answers


  1. The tenants many-side is wrong, it misses the cascade-specification.

    https://docs.oracle.com/javaee/6/api/javax/persistence/OneToMany.html#cascade()

    Defaults to no operations being cascaded.

    JPA did not expect the DeploymentSteps to disappear and rollback the transaction.

    Login or Signup to reply.
  2. You have the cascade in DeploymentStep but you are deleting the Tenant. To delete the DeploymentStep using the TenantRepository you should put the cascade in the Tenant entity.

    @Entity
    @Validated
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @TenantConstraints
    public class Tenant {
    
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tenant_gen")
      @SequenceGenerator(name="tenant_gen", sequenceName="tenant_seq", allocationSize=1)
      @JsonProperty("id")
      private Long id = null;
    
      @JsonIgnore
      @OneToMany(mappedBy = "tenant", fetch = FetchType.EAGER,cascade = CascadeType.ALL)
      private List<DeploymentStep> deploymentSteps = new ArrayList();
    
      ...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search