簡體   English   中英

錯誤:格式錯誤的記錄文字:- 帶有自定義類型數組的 JDBC 插入數據

[英]ERROR: malformed record literal: - JDBC insert data with self defined type array

我想用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 中的表

在此處輸入圖片說明

在此處輸入圖片說明

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM