【发布时间】:2018-07-14 14:17:00
【问题描述】:
一个同时使用 JPA 和验证注释的有效实体,例如
@Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
public static final int IMAGE_COUNT_MAX = 5;
@Id
@GeneratedValue
private Long id;
@Size(max = IMAGE_COUNT_MAX, message = "Maximal " + IMAGE_COUNT_MAX + " images are allowed")
@Basic
@Lob
private ArrayList<byte[]> imageData = new ArrayList<>();
导致@Size 的max 值作为LONG VARCHAR FOR BIT DATA 的长度属性传递,这在Apache Derby 中是无效的SQL,因此会导致
SEVERE: Error thrown executing CREATE TABLE MYENTITY
(
ID BIGINT NOT NULL generated always as identity (start with 1),
IMAGEDATA LONG VARCHAR FOR BIT DATA(5)
) : Syntax error: Encountered "(" at line 4, column 40.
java.sql.SQLSyntaxErrorException: Syntax error: Encountered "(" at line 4, column 40.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
at org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:291)
at org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:291)
at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatement(AbstractTable.java:849)
at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatementList(AbstractTable.java:800)
at org.datanucleus.store.rdbms.table.AbstractTable.create(AbstractTable.java:522)
at org.datanucleus.store.rdbms.table.AbstractTable.exists(AbstractTable.java:580)
at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.performTablesValidation(RDBMSStoreManager.java:3447)
at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.run(RDBMSStoreManager.java:2969)
at org.datanucleus.store.rdbms.AbstractSchemaTransaction.execute(AbstractSchemaTransaction.java:118)
at org.datanucleus.store.rdbms.RDBMSStoreManager.manageClasses(RDBMSStoreManager.java:1672)
at org.datanucleus.store.rdbms.RDBMSStoreManager.getDatastoreClass(RDBMSStoreManager.java:648)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.getDatastoreClass(RDBMSPersistenceHandler.java:88)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertObject(RDBMSPersistenceHandler.java:123)
at org.datanucleus.state.StateManagerImpl.internalMakePersistent(StateManagerImpl.java:4535)
at org.datanucleus.state.StateManagerImpl.flush(StateManagerImpl.java:5735)
at org.datanucleus.flush.FlushOrdered.execute(FlushOrdered.java:106)
at org.datanucleus.ExecutionContextImpl.flushInternal(ExecutionContextImpl.java:4058)
at org.datanucleus.ExecutionContextImpl.flush(ExecutionContextImpl.java:4004)
at org.datanucleus.api.jpa.JPAEntityManager.flush(JPAEntityManager.java:946)
at richtercloud.datanucleus.validation.schema.confusion.NewMain.main(NewMain.java:33)
Caused by: ERROR 42X01: Syntax error: Encountered "(" at line 4, column 40.
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.impl.sql.compile.ParserImpl.parseStatementOrSearchCondition(Unknown Source)
at org.apache.derby.impl.sql.compile.ParserImpl.parseStatement(Unknown Source)
at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
... 22 more
这可能是 - 难以理解 - JPA 或 DataNucleus 中的功能吗?如果是 - 我如何映射 JPA 中的字段并指定验证约束(如果可能,不涉及 XML 配置文件)?或者这是 DataNucleus 中的错误?
我正在使用
richtercloud:datanucleus-validation-schema-confusion:jar:1.0-SNAPSHOT
+- org.datanucleus:javax.persistence:jar:2.2.0-release:compile
+- org.datanucleus:datanucleus-api-jpa:jar:5.1.4:compile
+- org.datanucleus:datanucleus-core:jar:5.1.4:compile
+- org.datanucleus:datanucleus-rdbms:jar:5.1.4:compile
+- org.apache.derby:derbyclient:jar:10.14.1.0:compile
+- org.apache.derby:derby:jar:10.14.1.0:compile
\- org.hibernate:hibernate-validator:jar:4.3.2.Final:compile
+- javax.validation:validation-api:jar:1.0.0.GA:compile
\- org.jboss.logging:jboss-logging:jar:3.1.0.CR2:compile
@Column 中的 columnDefinition 被简单地忽略。应该不是这样吧?
我指的是和使用 DataNucleus JPA(而不是 JDO)。
SSCCE 可以在https://gitlab.com/krichter/datanucleus-validation-schema-confusion 找到。
【问题讨论】:
-
它应该是一个功能。引用 DataNucleus 文档:'Bean Validation annotations @Size(max=...) 和 @NotNull 的进一步使用是,如果您指定这些,则无需指定等效的 JDO“length”和“allowsNull”属性,因为它们等同于同一事物'(请参见此处:datanucleus.org/products/accessplatform_4_1/jdo/…)。您绝对需要使用 DataNucleus 吗?
-
我了解您的编辑与您认为上述评论不适用有关。请注意,DataNucleus 使用其 JDO 实现来模仿 JPA 功能,因此大多数“功能”也适用于 JPA。这是 JPA 的相关文档:datanucleus.org/products/accessplatform_4_1/jpa/…。 JPA 在 DataNucleus 中确实是二等公民,因此请为更多惊喜做好准备
-
@crizzis 感谢您的意见。如何关闭此“功能”?将
javax.persistence.validation.mode设置为none并没有帮助,因为它似乎会影响预持久验证而不是模式生成。 -
这很可能是不可能的。我只能建议使用 DataNucleus 提交错误报告(另外,冒着听起来有偏见的风险,让我重复一遍:你绝对需要使用 DataNucleus 吗?)
-
@crizzis,是的,您听起来有偏见,并且没有 datanucleus 不会使用 jdo 处理“模仿”jpa,该 api 也不是“二等公民”。将它用于 jpa 不需要 jdo 处理,并且多年来一直没有。请坚持事实
标签: java validation jpa datanucleus