I have the following entities with the one-to-one relationship:
@NoArgsConstructor
@Data
@DynamicUpdate
@Table(name = "product")
@Entity
public class Product implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(name = "id", updatable = false, nullable = false)
private UUID id;
@Column(name = "feed", length = 100, nullable = false)
private String feed;
// Omitted columns
@ToString.Exclude
@OneToOne(mappedBy = "product", cascade = CascadeType.ALL)
private PushPermission pushPermission;
}
@Data
@NoArgsConstructor
@Table(name = "push_permission")
@Entity
public class PushPermission implements Serializable {
@Id
@Column(name = "id", updatable = false, nullable = false)
private UUID id;
// Omitted columns
@ToString.Exclude
@OneToOne
@JoinColumn(name = "id")
@MapsId
private Product product;
}
I would like to update all records in PushPermission
where feed (column from Product) is not equal to PROMO
using JPA Criteria API.
I have used the following CriteriaUpdate
:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaUpdate<PushPermission> criteriaUpdate = cb.createCriteriaUpdate(PushPermission.class);
Root<PushPermission> root = criteriaUpdate.from(PushPermission.class);
criteriaUpdate.set("exampleField", true);
Predicate selectedProductsPredicate = root.get("id").in(ids);
Predicate skipFeedPredicate = cb.notEqual(root.get("product").get("feed"), "PROMO");
criteriaUpdate.where(cb.and(selectedProductsPredicate, skipFeedPredicate));
Query query = entityManager.createQuery(criteriaUpdate);
query.executeUpdate();
but I got the following error message:
ERROR: missing FROM-clause entry for table "p2_0"
Generated update statement by Hibernate:
update
push_permission
set
exampleField=?,
where
id in(?,?)
and p2_0.feed!=?
Besides I tried to use joining:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaUpdate<PushPermission> criteriaUpdate = cb.createCriteriaUpdate(PushPermission.class);
Root<PushPermission> root = criteriaUpdate.from(PushPermission.class);
Join<PushPermission, Product> productJoin = root.join("product");
criteriaUpdate.set("exampleField", true);
Predicate selectedProductsPredicate = root.get("id").in(ids);
Predicate skipFeedPredicate = cb.notEqual(productJoin.get("feed"), "PROMO");
criteriaUpdate.where(cb.and(selectedProductsPredicate, skipFeedPredicate));
Query query = entityManager.createQuery(criteriaUpdate);
query.executeUpdate();
but I got the following message:
The root node [me.foo.app.PushPermission] does not allow join/fetch
Hibernate didn't generate any update statement.
I use Postgres SQL 14.5 and I know I can do the native query which works:
update push_permission set exampleField=true from product where push_permission.id=product.id and product.feed<>'PROMO';
but I wonder I can do it with the use of JPA Criteria API.
I use Spring Boot 3.0.2 that implies Hibernate 6.