Spring JPA 无法搜索嵌套对象,尽管设置了级联属性



所以我有一个对象Product,比如说,具有私有字符串名称和私有起源。代码如下:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
public abstract class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NonNull
private String name;
@NonNull
@OneToOne(cascade = CascadeType.ALL)
private Origin origin;
}

现在我使用数据加载器在启动时将一些产品添加到数据库中,如下所示:

(Wine扩展了产品并增加了一些字符串(

repository.save(new Wine(
"Test wine"
new Origin(
"Crete",
"Greece"
)
));

此外,我有一个搜索端点,可以在其中搜索名称或原点。

public Page<Wine> searchProducts(
@RequestParam(name = "text", required = false) String searchTerm,
@RequestParam(required = false) Origin origin) {
return wineService.searchWines(
searchTerm,
origin
);
}

在葡萄酒服务中,我使用规范创建了一个查询。把它们都放在这里太夸张了,所以看看这个:

public static Specification<Wine> hasOrigin(Origin origin) {
return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.equal(root.get(Wine_.ORIGIN), origin);
}

奇怪的是,它在一段时间前似乎有效,但现在不行了。现在,如果我搜索一款有特定产地的葡萄酒,它只会显示:

org.hibernate.TransientObjectException:对象引用未保存的瞬态实例-在刷新前保存瞬态实例:[created].backend.model.Origin

如何修复此问题?我看到了大约5个关于这个问题的不同帖子,他们都说";好吧,只需将级联ALL添加到Object";但我从一开始就这么做了。

编辑:来源实体代码:

@Entity
@Data
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
@Table(name = "regions")
public class Origin {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonIgnore
private long id;
@NonNull
private String region;
@NonNull
private String country;
}

首先连接Origin,然后创建两个Predicate,并将它们添加到生成器中并返回。

public static Specification<Wine> hasOrigin(Origin origin) {
return new Specification<Wine>() {
@Override
public Predicate toPredicate(Root<Wine> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
final List<Predicate> predicates = new ArrayList<>();
Join<Wine, Origin> originRoot = root.join("origin");
predicates.add(criteriaBuilder.equal(originRoot.get("country"), origin.getCountry()));
predicates.add(criteriaBuilder.equal(originRoot.get("region"), origin.getRegion()));
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
}

最新更新