休眠:仅当参数不为null时,才将嵌入式字段与参数进行比较

时间:2019-02-27 10:19:39

标签: java hibernate

我有一个嵌入式字段,我想将其与传递的参数进行比较,但前提是此参数不为null。 对于常规(非嵌入式)字段,我可以使用以下查询,它将按预期运行:

FROM TestEntity entity where :embedded is null or entity.embedded = :embedded

但是对于嵌入式字段,Hibernate不能正确绑定参数,它绑定的参数比应有的更多。如您在下面的输出中看到的,有三个“?”但是四个绑定。那是一个休眠错误吗?

   2019-02-27 13:19:31,497 [DEBUG] org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:92) 
/* FROM TestEntity entity where  :embedded is null or entity.embedded = :embedded */ select testentity0_.id as id1_0_, testentity0_.emb_first as emb_firs2_0_, testentity0_.emb_second as emb_seco3_0_ from test testentity0_ where ? is null or testentity0_.emb_first=? and testentity0_.emb_second=?
2019-02-27 13:19:31,498 [TRACE] org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:53) 
binding parameter [1] as [VARCHAR] - [null]
2019-02-27 13:19:31,499 [TRACE] org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:53) 
binding parameter [2] as [VARCHAR] - [null]
2019-02-27 13:19:31,499 [TRACE] org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:53) 
binding parameter [3] as [VARCHAR] - [null]
2019-02-27 13:19:31,499 [TRACE] org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:53) 
binding parameter [4] as [VARCHAR] - [null]
2019-02-27 13:19:31,499 [WARN ] org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:129) 
SQL Error: 90008, SQLState: 90008
2019-02-27 13:19:31,499 [ERROR] org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:131) 
Недопустимое значение "4" для параметра "parameterIndex"
Invalid value "4" for parameter "parameterIndex" [90008-194]
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:147)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1419)
    at org.hibernate.Query.getResultList(Query.java:427)
    at Main.select(Main.java:48)
    at Main.main(Main.java:20)
Caused by: org.hibernate.exception.GenericJDBCException: could not execute query
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
    at org.hibernate.loader.Loader.doList(Loader.java:2618)
    at org.hibernate.loader.Loader.doList(Loader.java:2598)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430)
    at org.hibernate.loader.Loader.list(Loader.java:2425)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:370)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1481)
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1441)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1410)
    ... 3 more
Caused by: org.h2.jdbc.JdbcSQLException: Недопустимое значение "4" для параметра "parameterIndex"
Invalid value "4" for parameter "parameterIndex" [90008-194]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.getInvalidValueException(DbException.java:228)
    at org.h2.jdbc.JdbcPreparedStatement.setParameter(JdbcPreparedStatement.java:1436)
    at org.h2.jdbc.JdbcPreparedStatement.setNull(JdbcPreparedStatement.java:316)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:61)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:279)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:274)
    at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:336)
    at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:53)
    at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:628)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1956)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1909)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887)
    at org.hibernate.loader.Loader.doQuery(Loader.java:932)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
    at org.hibernate.loader.Loader.doList(Loader.java:2615)
    ... 12 more

TestEntity.java

import javax.persistence.*;

@Entity
@Table(name = "test")
public class TestEntity {
    @Id
    @GeneratedValue(generator = "test_seq")
    @SequenceGenerator(name = "test_seq", sequenceName="TEST_SEQ")
    @Column(name = "id")
    private int id;

    @Embedded
    private TestEmbedded embedded;

    public TestEntity() {
    }

    public TestEntity(TestEmbedded embedded) {
        this.embedded = embedded;
    }

    public int getId() {
        return id;
    }

    public TestEmbedded getEmbedded() {
        return embedded;
    }
}

TestEmbedded.java

import javax.persistence.*;

@Embeddable
public class TestEmbedded {
    @Column(name = "emb_first", nullable = false)
    private String embFirst;

    @Column(name = "emb_second", nullable = false)
    private String embSecond;

    public TestEmbedded() {
    }

    public TestEmbedded(String embFirst, String embSecond) {
        this.embFirst = embFirst;
        this.embSecond = embSecond;
    }

    public String getEmbFirst() {
        return embFirst;
    }

    public String getEmbSecond() {
        return embSecond;
    }
}

Main.java

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import java.util.List;
import java.util.Properties;

public class Main {
    public static void main(String[] args) {
        Properties entityManagerFactoryProperties = new Properties();

        entityManagerFactoryProperties.setProperty("javax.persistence.jdbc.driver", "org.h2.Driver");
        entityManagerFactoryProperties.setProperty("javax.persistence.jdbc.url", "jdbc:h2:mem:");
        entityManagerFactoryProperties.setProperty("javax.persistence.jdbc.user", "sa");
        entityManagerFactoryProperties.setProperty("javax.persistence.jdbc.password", "");

        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("main", entityManagerFactoryProperties);

        insert(entityManagerFactory);
        select(entityManagerFactory);
    }

    private static void insert(EntityManagerFactory entityManagerFactory) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        entityManager.getTransaction().begin();
        try {
            entityManager.persist(new TestEntity(new TestEmbedded("1", "2")));
            entityManager.persist(new TestEntity(new TestEmbedded("3", "2")));
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            throw e;
        } finally {
            entityManager.close();
        }
    }

    private static void select(EntityManagerFactory entityManagerFactory) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        String queryText = "FROM TestEntity entity where "
                + " :embedded is null or entity.embedded = :embedded";
        entityManager.getTransaction().begin();
        try {
            TypedQuery<TestEntity> query = entityManager.createQuery(queryText, TestEntity.class);
            query.setParameter("embedded", null);
            List<TestEntity> result = query.getResultList();
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            throw e;
        } finally {
            entityManager.close();
        }
    }
}

persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
    <persistence-unit name="main">
        <class>TestEntity</class>

        <exclude-unlisted-classes>true</exclude-unlisted-classes>

        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.use_sql_comments" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

0 个答案:

没有答案