Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql动态分区和Hibernate插入无法通过返回NULL的before Insert触发器工作_Hibernate_Database Partitioning_Hibernate 5.x_Postgresql 12 - Fatal编程技术网

Postgresql动态分区和Hibernate插入无法通过返回NULL的before Insert触发器工作

Postgresql动态分区和Hibernate插入无法通过返回NULL的before Insert触发器工作,hibernate,database-partitioning,hibernate-5.x,postgresql-12,Hibernate,Database Partitioning,Hibernate 5.x,Postgresql 12,Postgresql动态分区和Hibernate插入无法通过触发器工作 我有一个图形和节点表。图通过Node_id与节点表有一对一的关系,而节点表通过parent_id与自身有一个递归关系。每个节点表和图表都有租户名称,在多租户表中,我希望使用动态分区,如中所述 因此,我: CREATE TABLE IF NOT EXISTS graph ( id SERIAL NOT NULL, name character varying(255) NOT NULL, opt_lock_vers

Postgresql动态分区和Hibernate插入无法通过触发器工作

我有一个图形和节点表。图通过Node_id与节点表有一对一的关系,而节点表通过parent_id与自身有一个递归关系。每个节点表和图表都有租户名称,在多租户表中,我希望使用动态分区,如中所述

因此,我:

CREATE TABLE IF NOT EXISTS graph
(
  id SERIAL NOT NULL,
  name character varying(255) NOT NULL,
  opt_lock_version int NOT NUll default 1,
  type character varying(255) NOT NULL,
  tenant_name character varying(255) NOT NULL,
  node_id int,
  CONSTRAINT graph_pkey PRIMARY KEY (id),
  CONSTRAINT graph_node_fk FOREIGN KEY (node_id)
      REFERENCES node (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT graph_node_id_uk UNIQUE (node_id)
);

CREATE TABLE IF NOT EXISTS node
(
  id SERIAL NOT NULL,
  pending_removal boolean,
  tenant_name character varying(255) NOT NULL,
  name character varying(255) NOT NULL,
  type character varying(255) NOT NULL,
  parent_id int,
  CONSTRAINT node_pkey PRIMARY KEY (id),
  CONSTRAINT node_parent_id_fk FOREIGN KEY (parent_id)
      REFERENCES node (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
);
我已经存储了创建动态表的函数,并在动态创建的动态表中插入了一行(它可以正常工作):

现在的问题是Hibernate Insert用于图形表,由于store函数返回NULL,它返回“Insert 0”。Hibernate失败,批处理更新从更新[0]返回的意外行数为1;实际行数:0;预期:1;语句已执行。记录已插入到动态表中,但主表中的0行受到影响。我不想在主图表表中复制数据(它应该是空的),只有动态表才会有记录

如何伪造“插入0 1”或如何指示数据已插入休眠

更新:

我可以通过更改hibernate internalorg.hibernate.jdbc.Expectations类来伪造插入,该类检查受影响的记录,并通过threadlocal变量count将其iff设置为TRUE:唯一的问题是现在更新和删除语句没有tenant\u name,否则它不能满表扩展只需对租户进行分区,这样更新/删除速度就会很慢

/**
 * Holds various often used {@link Expectation} definitions.
 *
 * @author Steve Ebersole
 */
public class Expectations {

    **public static final ThreadLocal<Boolean> count_zero = new ThreadLocal<Boolean>();**

    private static final CoreMessageLogger LOG = CoreLogging.messageLogger( Expectations.class );

    private static SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper( false );

    public static final int USUAL_EXPECTED_COUNT = 1;
    public static final int USUAL_PARAM_POSITION = 1;


    // Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public static class BasicExpectation implements Expectation {
        private final int expectedRowCount;

        protected BasicExpectation(int expectedRowCount) {
            this.expectedRowCount = expectedRowCount;
            if ( expectedRowCount < 0 ) {
                throw new IllegalArgumentException( "Expected row count must be greater than zero" );
            }
        }

        public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
            rowCount = determineRowCount( rowCount, statement );
            if ( batchPosition < 0 ) {
                checkNonBatched( rowCount, statement );
            }
            else {
                checkBatched( rowCount, batchPosition, statement );
            }
        }

        private void checkBatched(int rowCount, int batchPosition, PreparedStatement statement) {
            if ( rowCount == -2 ) {
                LOG.debugf( "Success of batch update unknown: %s", batchPosition );
            }
            else if ( rowCount == -3 ) {
                throw new BatchFailedException( "Batch update failed: " + batchPosition );
            }
            else {
                if ( expectedRowCount > rowCount ) {
                    **if(count_zero.get() == null || count_zero.get()) {**
                        throw new StaleStateException(
                                "Batch update returned unexpected row count from update ["
                                        + batchPosition + "]; actual row count: " + rowCount
                                        + "; expected: " + expectedRowCount + "; statement executed: "
                                        + statement
                        );
                    }
                }
                if ( expectedRowCount < rowCount ) {
                    **if(count_zero.get() == null || count_zero.get()) {**
                        String msg = "Batch update returned unexpected row count from update [" +
                                batchPosition + "]; actual row count: " + rowCount +
                                "; expected: " + expectedRowCount;
                        throw new BatchedTooManyRowsAffectedException(msg, expectedRowCount, rowCount, batchPosition);
                    }
                }
            }
        }

        private void checkNonBatched(int rowCount, PreparedStatement statement) {
            if ( expectedRowCount > rowCount ) {
                **if(count_zero.get() == null || count_zero.get()) {**
                    throw new StaleStateException(
                            "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount
                                    + "; statement executed: " + statement
                    );
                }
            }
            if ( expectedRowCount < rowCount ) {
                **if(count_zero.get() == null || count_zero.get()) {**
                    String msg = "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount;
                    throw new TooManyRowsAffectedException(msg, expectedRowCount, rowCount);
                }
            }
        }

        public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
            return 0;
        }

        public boolean canBeBatched() {
            return true;
        }

        protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
            return reportedRowCount;
        }
    }

    public static class BasicParamExpectation extends BasicExpectation {
        private final int parameterPosition;

        protected BasicParamExpectation(int expectedRowCount, int parameterPosition) {
            super( expectedRowCount );
            this.parameterPosition = parameterPosition;
        }

        @Override
        public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
            toCallableStatement( statement ).registerOutParameter( parameterPosition, Types.NUMERIC );
            return 1;
        }

        @Override
        public boolean canBeBatched() {
            return false;
        }

        @Override
        protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
            try {
                return toCallableStatement( statement ).getInt( parameterPosition );
            }
            catch (SQLException sqle) {
                sqlExceptionHelper.logExceptions( sqle, "could not extract row counts from CallableStatement" );
                throw new GenericJDBCException( "could not extract row counts from CallableStatement", sqle );
            }
        }

        private CallableStatement toCallableStatement(PreparedStatement statement) {
            if ( !CallableStatement.class.isInstance( statement ) ) {
                throw new HibernateException(
                        "BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass()
                );
            }
            return (CallableStatement) statement;
        }
    }


    // Various Expectation instances ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public static final Expectation NONE = new Expectation() {
        public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
            // explicitly doAfterTransactionCompletion no checking...
        }

        public int prepare(PreparedStatement statement) {
            return 0;
        }

        public boolean canBeBatched() {
            return true;
        }
    };

    public static final Expectation BASIC = new BasicExpectation( USUAL_EXPECTED_COUNT );

    public static final Expectation PARAM = new BasicParamExpectation( USUAL_EXPECTED_COUNT, USUAL_PARAM_POSITION );


    public static Expectation appropriateExpectation(ExecuteUpdateResultCheckStyle style) {
        if ( style == ExecuteUpdateResultCheckStyle.NONE ) {
            return NONE;
        }
        else if ( style == ExecuteUpdateResultCheckStyle.COUNT ) {
            return BASIC;
        }
        else if ( style == ExecuteUpdateResultCheckStyle.PARAM ) {
            return PARAM;
        }
        else {
            throw new HibernateException( "unknown check style : " + style );
        }
    }

    private Expectations() {
    }
}
/**
*保存各种常用的{@link expection}定义。
*
*@作者史蒂夫·埃伯索尔
*/
公众阶级的期望{
**public static final ThreadLocal count_zero=new ThreadLocal()**
私有静态最终CoreMessageLogger日志=CoreLogging.messageLogger(Expectations.class);
私有静态SqlExceptionHelper SqlExceptionHelper=新SqlExceptionHelper(false);
公共静态最终整数通常\预期\计数=1;
公共静态最终int通常参数位置=1;
//基本期望~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
公共静态类BasicExpection实现了预期{
私人最终int expectedRowCount;
受保护的基本预期(int-expectedRowCount){
this.expectedRowCount=expectedRowCount;
如果(预期的rowCount<0){
抛出新的IllegalArgumentException(“预期行计数必须大于零”);
}
}
公开最终无效验证结果(整数行数、预处理语句、整数批位置){
rowCount=determineRowCount(rowCount,语句);
if(批位置<0){
checkNonBatched(行计数、语句);
}
否则{
checkBatched(行计数、batchPosition、语句);
}
}
私有void checkbatch(int rowCount、int batchPosition、PreparedStatement语句){
如果(行计数==-2){
LOG.debugf(“批更新成功未知:%s”,batchPosition);
}
else if(行计数==-3){
抛出新的BatchFailedException(“批更新失败:+batchPosition”);
}
否则{
如果(expectedRowCount>rowCount){
**if(count_zero.get()==null | | count_zero.get()){**
抛出新的StaleStateException(
“批处理更新从更新[]返回了意外的行数”
+batchPosition+“];实际行计数:“+rowCount”
+应执行“+expectedRowCount+”语句:
+声明
);
}
}
如果(预期的行数<行数){
**if(count_zero.get()==null | | count_zero.get()){**
String msg=“批处理更新从更新返回意外的行数[”+
batchPosition+“];实际行计数:“+rowCount”+
“预期:”+expectedRowCount;
抛出新的BatchedTooManyRowsAffectedException(msg、expectedRowCount、rowCount、batchPosition);
}
}
}
}
私有void checknonbatch(int行计数、PreparedStatement语句){
如果(expectedRowCount>rowCount){
**if(count_zero.get()==null | | count_zero.get()){**
抛出新的StaleStateException(
意外的行计数:“+rowCount+”;应为:“+expectedRowCount”
+“已执行语句:”+语句
);
}
}
如果(预期的行数<行数){
**if(count_zero.get()==null | | count_zero.get()){**
字符串msg=“意外的行数:”+rowCount+”;预期:“+expectedRowCount;
抛出新的ToomAnyRowAffectedException(msg、expectedRowCount、rowCount);
}
}
}
public int prepare(PreparedStatement语句)抛出SQLException、HibernateeException{
返回0;
}
公共布尔值可批处理(){
返回true;
}
受保护的int determinerRowCount(int reportedRowCount,PreparedStatement语句){
返回reportedRowCount;
}
}
公共静态类BasicParamExpection扩展了BasicExpection{
私有最终int参数位置;
受保护的BasicParamExpection(int expect
/**
 * Holds various often used {@link Expectation} definitions.
 *
 * @author Steve Ebersole
 */
public class Expectations {

    **public static final ThreadLocal<Boolean> count_zero = new ThreadLocal<Boolean>();**

    private static final CoreMessageLogger LOG = CoreLogging.messageLogger( Expectations.class );

    private static SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper( false );

    public static final int USUAL_EXPECTED_COUNT = 1;
    public static final int USUAL_PARAM_POSITION = 1;


    // Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public static class BasicExpectation implements Expectation {
        private final int expectedRowCount;

        protected BasicExpectation(int expectedRowCount) {
            this.expectedRowCount = expectedRowCount;
            if ( expectedRowCount < 0 ) {
                throw new IllegalArgumentException( "Expected row count must be greater than zero" );
            }
        }

        public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
            rowCount = determineRowCount( rowCount, statement );
            if ( batchPosition < 0 ) {
                checkNonBatched( rowCount, statement );
            }
            else {
                checkBatched( rowCount, batchPosition, statement );
            }
        }

        private void checkBatched(int rowCount, int batchPosition, PreparedStatement statement) {
            if ( rowCount == -2 ) {
                LOG.debugf( "Success of batch update unknown: %s", batchPosition );
            }
            else if ( rowCount == -3 ) {
                throw new BatchFailedException( "Batch update failed: " + batchPosition );
            }
            else {
                if ( expectedRowCount > rowCount ) {
                    **if(count_zero.get() == null || count_zero.get()) {**
                        throw new StaleStateException(
                                "Batch update returned unexpected row count from update ["
                                        + batchPosition + "]; actual row count: " + rowCount
                                        + "; expected: " + expectedRowCount + "; statement executed: "
                                        + statement
                        );
                    }
                }
                if ( expectedRowCount < rowCount ) {
                    **if(count_zero.get() == null || count_zero.get()) {**
                        String msg = "Batch update returned unexpected row count from update [" +
                                batchPosition + "]; actual row count: " + rowCount +
                                "; expected: " + expectedRowCount;
                        throw new BatchedTooManyRowsAffectedException(msg, expectedRowCount, rowCount, batchPosition);
                    }
                }
            }
        }

        private void checkNonBatched(int rowCount, PreparedStatement statement) {
            if ( expectedRowCount > rowCount ) {
                **if(count_zero.get() == null || count_zero.get()) {**
                    throw new StaleStateException(
                            "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount
                                    + "; statement executed: " + statement
                    );
                }
            }
            if ( expectedRowCount < rowCount ) {
                **if(count_zero.get() == null || count_zero.get()) {**
                    String msg = "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount;
                    throw new TooManyRowsAffectedException(msg, expectedRowCount, rowCount);
                }
            }
        }

        public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
            return 0;
        }

        public boolean canBeBatched() {
            return true;
        }

        protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
            return reportedRowCount;
        }
    }

    public static class BasicParamExpectation extends BasicExpectation {
        private final int parameterPosition;

        protected BasicParamExpectation(int expectedRowCount, int parameterPosition) {
            super( expectedRowCount );
            this.parameterPosition = parameterPosition;
        }

        @Override
        public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
            toCallableStatement( statement ).registerOutParameter( parameterPosition, Types.NUMERIC );
            return 1;
        }

        @Override
        public boolean canBeBatched() {
            return false;
        }

        @Override
        protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
            try {
                return toCallableStatement( statement ).getInt( parameterPosition );
            }
            catch (SQLException sqle) {
                sqlExceptionHelper.logExceptions( sqle, "could not extract row counts from CallableStatement" );
                throw new GenericJDBCException( "could not extract row counts from CallableStatement", sqle );
            }
        }

        private CallableStatement toCallableStatement(PreparedStatement statement) {
            if ( !CallableStatement.class.isInstance( statement ) ) {
                throw new HibernateException(
                        "BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass()
                );
            }
            return (CallableStatement) statement;
        }
    }


    // Various Expectation instances ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public static final Expectation NONE = new Expectation() {
        public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
            // explicitly doAfterTransactionCompletion no checking...
        }

        public int prepare(PreparedStatement statement) {
            return 0;
        }

        public boolean canBeBatched() {
            return true;
        }
    };

    public static final Expectation BASIC = new BasicExpectation( USUAL_EXPECTED_COUNT );

    public static final Expectation PARAM = new BasicParamExpectation( USUAL_EXPECTED_COUNT, USUAL_PARAM_POSITION );


    public static Expectation appropriateExpectation(ExecuteUpdateResultCheckStyle style) {
        if ( style == ExecuteUpdateResultCheckStyle.NONE ) {
            return NONE;
        }
        else if ( style == ExecuteUpdateResultCheckStyle.COUNT ) {
            return BASIC;
        }
        else if ( style == ExecuteUpdateResultCheckStyle.PARAM ) {
            return PARAM;
        }
        else {
            throw new HibernateException( "unknown check style : " + style );
        }
    }

    private Expectations() {
    }
}