在我的情况下,如何使用枚举执行弹簧数据JPA查询?
首先,这很长,但我想提供所有可能的信息。
我正在研究一个更大的查询,这将基于此基础,因此我没有采用更轻松或其他方法。此外,我无法真正改变我们实现DB和域对象的方式。
我的问题是我无法获得弹簧数据JPA查询来与枚举一起使用。该领域也是DB中的枚举。这是缩写的代码。
2个表的SQL:
CREATE TABLE my_order (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
creation_date TIMESTAMP NOT NULL,
);
CREATE TYPE ORDER_STATE as ENUM ('new', 'open', 'closed');
CREATE CAST (CHARACTER VARYING AS ORDER_STATE) WITH INOUT AS IMPLICIT;
CREATE TABLE my_order_history (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
order_date TIMESTAMP NOT NULL,
order_state ORDER_STATE NOT NULL,
order_id INT REFERENCES my_order
);
这是相应的域对象:
@Entity
@Table(name = "my_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "creation_date")
private Date creationDate;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<OrderHistory> orderHistories;
}
@Entity
@Table(name = "my_order_history")
public class OrderHistory {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "order_date ")
private Date orderDate;
@Column(name = "order_state")
@Convert(converter = OrderStateConverter.class)
private OrderState orderState
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
这是转换器:
@Component
@Converter(autoApply = true)
public class OrderStateConverter implement AttributeConverter<OrderState, String> {
@Override
public String convertToDatabaseColumn(OrderState attribute) {
return attribute.getValue;
}
@Override
public OrderState convertToEntityAttribute(String dbData) {
return OrderState.fromValue(dbData);
}
}
这是枚举:
public enum OrderState {
NEW("new"), OPEN("open"), CLOSED("closed");
@Getter
private String value;
private OrderState(String value) {
this.value = value;
}
public static OrderState fromValue(String value) {
for (OrderState orderState : values()) {
if (orderState.getValue().equals(value)) {
return orderState;
}
}
return null;
}
}
这是我的弹簧存储库。我将尝试的三种方法放在下面,然后在下面给您每个人都会收到的例外:
@Repository
public interface OrderRepository extends PagingAndSortingRepository<Order, Long> {
@Query("SELECT o FROM Order o JOIN o.orderHistories oh WHERE oh.orderState = :orderState")
List<Order> getOrdersByOrderState1(@Param("orderState") OrderState orderState);
@Query("SELECT o FROM Order o JOIN o.orderHistories oh WHERE oh.orderState = :orderState")
List<Order> getOrdersByOrderState2(@Param("orderState") String orderState);
@Query("SELECT o FROM Order o JOIN o.orderHistories oh WHERE oh.orderState = :#(#orderState?.getValue())")
List<Order> getOrdersByOrderState3(@Param("orderState") OrderState orderState);
}
对于#1,当我提供一个阶层枚举时,我会得到以下例外:
Caused by: org.postgres.util.PSQLException: ERROR: operator does not exist: order_state = character varying
Hint: No operator matches the given name and argument types. You might need explicit type casts.
对于#2,当我提供Orderstate.getValue()时,这是一个字符串,我会得到以下例外:
java.jang.IllegalArgumentException: Parameter value [new] did not match expected type [com.testing.enums.OrderState (n/a)]
对于#3,当我提供一个阶梯枚举时,我会得到以下例外(与#2相同):
java.jang.IllegalArgumentException: Parameter value [new] did not match expected type [com.testing.enums.OrderState (n/a)]
基本上,我尝试发送枚举并获得错误,但我也得到了一个当我尝试发送字符串时,错误。有什么我能做的吗?到底发生了什么?
First sorry this is long but I wanted to provide all information possible.
I am working on a much larger query that will build on this hence the reason I am not taking an easier or other approaches. In addition I can't really change the way we implemented the DB and Domain Objects.
My problem is I can't get a Spring Data JPA Query to work with an Enum. The field is an Enum in the DB as well. Here is the abbreviated code.
The SQL for the 2 tables:
CREATE TABLE my_order (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
creation_date TIMESTAMP NOT NULL,
);
CREATE TYPE ORDER_STATE as ENUM ('new', 'open', 'closed');
CREATE CAST (CHARACTER VARYING AS ORDER_STATE) WITH INOUT AS IMPLICIT;
CREATE TABLE my_order_history (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
order_date TIMESTAMP NOT NULL,
order_state ORDER_STATE NOT NULL,
order_id INT REFERENCES my_order
);
Here is the corresponding Domain Objects:
@Entity
@Table(name = "my_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "creation_date")
private Date creationDate;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<OrderHistory> orderHistories;
}
@Entity
@Table(name = "my_order_history")
public class OrderHistory {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "order_date ")
private Date orderDate;
@Column(name = "order_state")
@Convert(converter = OrderStateConverter.class)
private OrderState orderState
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
Here is the converter:
@Component
@Converter(autoApply = true)
public class OrderStateConverter implement AttributeConverter<OrderState, String> {
@Override
public String convertToDatabaseColumn(OrderState attribute) {
return attribute.getValue;
}
@Override
public OrderState convertToEntityAttribute(String dbData) {
return OrderState.fromValue(dbData);
}
}
Here is the Enum:
public enum OrderState {
NEW("new"), OPEN("open"), CLOSED("closed");
@Getter
private String value;
private OrderState(String value) {
this.value = value;
}
public static OrderState fromValue(String value) {
for (OrderState orderState : values()) {
if (orderState.getValue().equals(value)) {
return orderState;
}
}
return null;
}
}
Here is my Spring Repo. I am putting the 3 ways I have tried and then below I will give you the exceptions I am receiving with each:
@Repository
public interface OrderRepository extends PagingAndSortingRepository<Order, Long> {
@Query("SELECT o FROM Order o JOIN o.orderHistories oh WHERE oh.orderState = :orderState")
List<Order> getOrdersByOrderState1(@Param("orderState") OrderState orderState);
@Query("SELECT o FROM Order o JOIN o.orderHistories oh WHERE oh.orderState = :orderState")
List<Order> getOrdersByOrderState2(@Param("orderState") String orderState);
@Query("SELECT o FROM Order o JOIN o.orderHistories oh WHERE oh.orderState = :#(#orderState?.getValue())")
List<Order> getOrdersByOrderState3(@Param("orderState") OrderState orderState);
}
For #1 when I provide an OrderState enum I get the following exception:
Caused by: org.postgres.util.PSQLException: ERROR: operator does not exist: order_state = character varying
Hint: No operator matches the given name and argument types. You might need explicit type casts.
For #2 when I provide OrderState.getValue(), which is a String, I get the following exception:
java.jang.IllegalArgumentException: Parameter value [new] did not match expected type [com.testing.enums.OrderState (n/a)]
For #3 when I provide an OrderState enum I get the following exception (same as #2):
java.jang.IllegalArgumentException: Parameter value [new] did not match expected type [com.testing.enums.OrderState (n/a)]
Basically I try to send in the enum and get an error but I also get an error when I try to send in a String. Is there anything I can do? What is exactly happening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论