【问题标题】:ERROR: malformed record literal: - JDBC insert data with self defined type array错误:格式错误的记录文字:- JDBC 使用自定义类型数组插入数据
【发布时间】:2020-06-07 07:03:02
【问题描述】:

我想用 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');

【问题讨论】:

    标签: java postgresql jdbc


    【解决方案1】:

    我遇到了同样的错误,似乎是 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

    【讨论】:

      猜你喜欢
      • 2015-06-05
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多