Incorrect support of "XML-mapped" column for enums in class
"org.apache.openjpa.kernel.exps.AbstractExpressionBuilder"
----------------------------------------------------------------------------------------------------------------------
Key: OPENJPA-2046
URL: https://issues.apache.org/jira/browse/OPENJPA-2046
Project: OpenJPA
Issue Type: Bug
Components: kernel
Affects Versions: 2.1.0
Reporter: Roman Solo
Class "org.apache.openjpa.kernel.exps.AbstractExpressionBuilder"
method "protected Value traversePath(Path path, String field, boolean pcOnly,
boolean allowNull)"
line 314 :
// xmlsupport xpath
XMLMetaData xmlmeta =
fmd.getRepository().getXMLMetaData(fmd.getDeclaredType());
if (xmlmeta != null) {
path.get(fmd, xmlmeta);
return path;
}
This lines are "indirectly" responsible for determine type of FieldMetaData -
is it an XML-mapped colomn or not. The logic inside method "PCPath#get(fmd,
xmlmeta)" is not so clear - it contains some strange assumption that such
method used only for XPATH-pathes and "PCPath" object will change his type just
after invocation of the "#get(fmd, xmlmeta)" method.
As a result in pointed above class "AbstractExpressionBuilder
" in line 316 we making a wrong conclusion because in accordance with
documentation
http://openjpa.apache.org/docs/latest/manual.html#ref_guide_xmlmapping an
XML-mapped column should has specific @Strategy annotation -
@Strategy("org.apache.openjpa.jdbc.meta.strats.XMLValueHandler") but not only
be type of class that marked by @XmlRootElement annotation. So, the equation
"xmlmeta != null" in line 316 is not enough and we should take into
consideration some additional meta-info.
I would like to propose to change all that "IF" to something like:
// xmlsupport xpath
if (((FieldMapping) fmd).getHandler() instanceof XMLValueHandler) {
XMLMetaData xmlmeta =
fmd.getRepository().getXMLMetaData(fmd.getDeclaredType());
if (xmlmeta != null) {
path.get(fmd, xmlmeta);
return path;
}
}
What the problem will be solved? Now it is impossible to use any persistent
enum-properties marked by annotation @Enumerated if their type has the
@XmlRootElement annotation too. You will get an Exception on execution of any
JPQL-query with such field in WHERE like this:
Caused by: <openjpa-2.1.0-r422266:1071316 fatal general error>
org.apache.openjpa.persistence.PersistenceException: The database dictionary in
use ("class ..... Dictionary") reports that it does not have feature
"SupportsXMLColumn". This feature is needed to complete the current operation.
To force OpenJPA to try to use the feature anyway, set the following property:
openjpa.jdbc.DBDictionary: SupportsXMLColumn=<value>
at
org.apache.openjpa.jdbc.sql.DBDictionary.assertSupport(DBDictionary.java:2736)
at
org.apache.openjpa.jdbc.sql.DBDictionary.appendXmlComparison(DBDictionary.java:2926)
at
org.apache.openjpa.jdbc.sql.DBDictionary.comparison(DBDictionary.java:2877)
at
org.apache.openjpa.jdbc.kernel.exps.EqualExpression.appendTo(EqualExpression.java:61)
at
org.apache.openjpa.jdbc.kernel.exps.CompareEqualExpression.appendTo(CompareEqualExpression.java:108)
at
org.apache.openjpa.jdbc.kernel.exps.AndExpression.appendTo(AndExpression.java:65)
at
org.apache.openjpa.jdbc.kernel.exps.BindVariableAndExpression.appendTo(BindVariableAndExpression.java:57)
at
org.apache.openjpa.jdbc.kernel.exps.SelectConstructor.buildWhere(SelectConstructor.java:312)
at
org.apache.openjpa.jdbc.kernel.exps.SelectConstructor.evaluate(SelectConstructor.java:94)
at
org.apache.openjpa.jdbc.kernel.JDBCStoreQuery.createWhereSelects(JDBCStoreQuery.java:360)
at
org.apache.openjpa.jdbc.kernel.JDBCStoreQuery.executeQuery(JDBCStoreQuery.java:193)
at
org.apache.openjpa.kernel.ExpressionStoreQuery$DataStoreExecutor.executeQuery(ExpressionStoreQuery.java:782)
at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1005)
For example, with the entity class like this
@Entity
@Table(name = "Mailbox")
public class Mailbox implements Serializable{
@Column(name = "user_id")
private Long userId;
@Column(name = "type")
@Enumerated(value = EnumType.ORDINAL)
private MailboxType type;
}
and enum class like
@XmlRootElement(name = "mailboxType")
@XmlEnum
public enum MailboxType {
LOCAL, EXTERNAL
}
it is impossible to execute a query like
"select mailbox FROM Mailbox mailbox WHERE mailbox.type = ?1"
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira