java - 错误: malformed record literal: - JDBC insert data with self defined type array

标签 java postgresql jdbc

我想用 JDBC 向 PostgreSQL 插入数据, 并且数据包含一个自定义类型的数组。 当我尝试插入并出现错误时。

谁能指出我哪里做错了?

String query = "INSERT INTO fitness_club (club_id, club_brand, club_name, latitude, longitude, club_status, club_home_url, address, open_hour) VALUES(?, ?::fitness_brand, ?, ?, ?, ?, ?, ?, ?)";

            PreparedStatement pst = conn.prepareStatement(query);

            pst.setInt(1, firstClub.getClubId());
            pst.setString(2, firstClub.getBrand().toString());
            pst.setString(3, firstClub.getDescription());
            pst.setDouble(4, firstClub.getLatitude());
            pst.setDouble(5, firstClub.getLongitude());
            pst.setInt(6, firstClub.getClubStatus());
            pst.setString(7, firstClub.getClubHomeUrl());
            pst.setString(8, firstClub.getAddress());

            Array arrayOpenHour = conn.createArrayOf("open_hour", firstClub.getOpenHours().toArray());

            pst.setArray(9, arrayOpenHour);

            ResultSet saveRS = pst.executeQuery();

这是错误消息

org.postgresql.util.PSQLException: ERROR: malformed record literal: "OpenHour@342c38f8"
  Detail: Missing left parenthesis.
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2510)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2245)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:311)

自定义类型

public class OpenHour {

    DayOfWeek day;

    String time;

}

数据表

create table fitness_club
(
    club_uid      uuid             not null
        constraint fitness_club_pkey
            primary key,
    club_brand    fitness_brand    not null,
    club_id       integer          not null,
    club_name     varchar(500)     not null,
    latitude      double precision not null,
    longitude     double precision not null,
    club_status   integer,
    club_home_url varchar(500),
    zip_code      varchar(500),
    address       varchar(500),
    city          varchar(500),
    state         us_state,
    open_hour     open_hour[],
    constraint brand_id_constrain
        unique (club_brand, club_id)
);
create type open_hour as
(
    day   week_day,
    hours varchar(50)
);

自定义类型被其他类型使用

create type week_day as enum ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');

最佳答案

我遇到了同样的错误,似乎是 createArrayOf 中序列化的问题。我改变了解决方案,发送了 JSON 格式的文本。

我分享我的解决方案,希望它对您有用。

1.- 模型

订单

@Getter
@Setter
@ToString
public class Order {
    private String orderId;
    private String customerId;
    private Date createdAt;
    private List<OrderProduct> orderProductList;
    private Double amountOrder;

    public Double getAmountOrder() {
        return orderProductList.stream().mapToDouble(OrderProduct::getAmount).sum();
    }
}

订购产品

@Getter
@Setter
@ToString
@AllArgsConstructor
public class OrderProduct implements Serializable {

    private static final long serialVersionUID = 1L;

    private int orderProductId;
    private int quantity;
    private String productId;
    private Double productPrice;

    Double getAmount() {
        return productPrice.doubleValue() * this.getQuantity();
    }
}

2.- 连接并向Postgresql发送数据,检查参数5

@Repository
public class OrderRepositoryAdapter implements CreateOrderPort 
{

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void createOrder(Order order) throws GlobalException {

        final String procedureCall = "{ ? = call create_order(?, ?, ?, ?)}";

        try (Connection connection = jdbcTemplate.getDataSource().getConnection();
             CallableStatement callableStatement = connection.prepareCall(procedureCall)
        ) {
            Gson gson = new Gson();
            String json = gson.toJson(order.getOrderProductList());

            callableStatement.registerOutParameter(1, Types.BIGINT);
            callableStatement.setString(2, order.getCustomerId());
            callableStatement.setTimestamp(3, new java.sql.Timestamp(order.getCreatedAt().getTime()));
            callableStatement.setDouble(4, order.getAmountOrder());
            callableStatement.setString(5, json);

            callableStatement.execute();

            order.setOrderId(Long.toString(callableStatement.getLong(1)));
        } catch (Exception e) {
            throw new GlobalException("Exception createOrder: " + e.getMessage());
        }
    }
}

3- Postgresql 中的函数,检查参数“p_order_product”

CREATE OR REPLACE FUNCTION public.create_order(
    p_customer_id character varying,
    p_created_at timestamp with time zone,
    p_amount_order double precision,
    p_order_product text)
    RETURNS bigint
    LANGUAGE 'plpgsql'

AS $BODY$
DECLARE
    p_order_id bigint;
    p_order_product_id bigint;
    p_json json;
BEGIN
    p_order_id := nextval('order_id_seq');
    INSERT INTO public."ORDERS"(
        order_id, customer_id, created_at, amount_order)
    VALUES (p_order_id, p_customer_id, p_created_at, p_amount_order);

    FOR p_json IN SELECT * FROM json_array_elements(p_order_product::json)
    LOOP
        p_order_product_id := nextval('order_product_id_seq');
            INSERT INTO public."ORDERS_PRODUCTS"(
                order_product_id, quantity, product_id, product_price, order_id)
            VALUES (p_order_product_id, CAST (p_json->>'quantity' AS bigint) , p_json->>'productId', CAST(p_json->>'productPrice' AS double precision), p_order_id);
    END LOOP;

    RETURN p_order_id;

END;
$BODY$;

4.- API 休息

http://localhost:3002/v1/orders

{
    "customerId":"5ed047dda2923f1ac2c64463",
    "createdAt":"2020-06-06T00:10:12",
    "orderProductList": 
    [{
            "quantity":"2",
            "productId":"5ed31ddb669529409edc2fd0",
            "productPrice": 1099.51

    },{
            "quantity":"1",
            "productId":"5ed31cb5669529409edc2fcf",
            "productPrice": 2199.99

    }]

}

5.- Postgresql 中的表

enter image description here

enter image description here

6.- 您可以在我的 GitHub 存储库中查看完整示例

https://github.com/JonathanM2ndoza/Hexagonal-Architecture-DDD/tree/master/Order

关于java - 错误: malformed record literal: - JDBC insert data with self defined type array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60631679/

相关文章:

java - SQLException : Invalid Column Name. ..?

jdbc - 如何使用存储过程配置 Kafka JDBC Source Connector?

java - 带有 docx4j 的 HTML/CSS 形状

java - Scala 隐式 Long 到可序列化

postgresql - 使用等式作为 View 创建的一部分

sql - 将 CamelCase 转换为 snake_case

apache - 使用 mod_proxy_ajp 连接 Apache 和 Tomcat 有效,但 JDBC 然后失败

JavaFX - 加载自定义控件的样式表

java - 在 Android 中通过 onCreate 使用 onSaveInstanceState 检索数据

postgresql - 文本字段相等