mirror of https://github.com/apache/openjpa.git
OPENJPA-2849 proper handling of different Date types
This commit is contained in:
parent
477d73a996
commit
25af7c35ee
|
@ -132,6 +132,11 @@ abstract class UnaryOp
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
Class<?> type = getType();
|
Class<?> type = getType();
|
||||||
int typeCode = type != null ? JavaTypes.getTypeCode(type) : JavaSQLTypes.JDBC_DEFAULT;
|
int typeCode = type != null ? JavaTypes.getTypeCode(type) : JavaSQLTypes.JDBC_DEFAULT;
|
||||||
|
if (typeCode == JavaTypes.DATE) {
|
||||||
|
// further clarify which date exactly
|
||||||
|
typeCode = JavaSQLTypes.getDateTypeCode(type);
|
||||||
|
}
|
||||||
|
|
||||||
Object value = res.getObject(this, typeCode, null);
|
Object value = res.getObject(this, typeCode, null);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if (nullableValue(ctx, state)) { // OPENJPA-1794
|
if (nullableValue(ctx, state)) { // OPENJPA-1794
|
||||||
|
|
|
@ -1,160 +1,184 @@
|
||||||
/*
|
/*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
* distributed with this work for additional information
|
* distributed with this work for additional information
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
* to you under the Apache License, Version 2.0 (the
|
* to you under the Apache License, Version 2.0 (the
|
||||||
* "License"); you may not use this file except in compliance
|
* "License"); you may not use this file except in compliance
|
||||||
* with the License. You may obtain a copy of the License at
|
* with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing,
|
||||||
* software distributed under the License is distributed on an
|
* software distributed under the License is distributed on an
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
* KIND, either express or implied. See the License for the
|
* KIND, either express or implied. See the License for the
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.jira1794;
|
package org.apache.openjpa.jira1794;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import java.util.Date;
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
@Entity
|
import javax.persistence.Table;
|
||||||
@Table(name = "j1794_ae")
|
|
||||||
public class AggEntity {
|
@Entity
|
||||||
|
@Table(name = "j1794_ae")
|
||||||
@Id
|
public class AggEntity {
|
||||||
@GeneratedValue
|
|
||||||
private int id;
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
private short pshortVal;
|
private int id;
|
||||||
private Short shortVal;
|
|
||||||
|
private short pshortVal;
|
||||||
private int pintVal;
|
private Short shortVal;
|
||||||
private Integer intVal;
|
|
||||||
|
private int pintVal;
|
||||||
private long plongVal;
|
private Integer intVal;
|
||||||
private Long longVal;
|
|
||||||
|
private long plongVal;
|
||||||
private float pfloatVal;
|
private Long longVal;
|
||||||
private Float floatVal;
|
|
||||||
|
private float pfloatVal;
|
||||||
private double pdblVal;
|
private Float floatVal;
|
||||||
private Double dblVal;
|
|
||||||
|
private double pdblVal;
|
||||||
private String stringVal;
|
private Double dblVal;
|
||||||
|
|
||||||
public void setId(int id) {
|
private String stringVal;
|
||||||
this.id = id;
|
|
||||||
}
|
private java.util.Date utilDate;
|
||||||
|
|
||||||
public int getId() {
|
private java.sql.Date sqlDate;
|
||||||
return id;
|
|
||||||
}
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
public void setPshortVal(short pshortVal) {
|
}
|
||||||
this.pshortVal = pshortVal;
|
|
||||||
}
|
public int getId() {
|
||||||
|
return id;
|
||||||
public short getPshortVal() {
|
}
|
||||||
return pshortVal;
|
|
||||||
}
|
public void setPshortVal(short pshortVal) {
|
||||||
|
this.pshortVal = pshortVal;
|
||||||
public void setShortVal(Short pShortVal) {
|
}
|
||||||
this.shortVal = pShortVal;
|
|
||||||
}
|
public short getPshortVal() {
|
||||||
|
return pshortVal;
|
||||||
public Short getShortVal() {
|
}
|
||||||
return shortVal;
|
|
||||||
}
|
public void setShortVal(Short pShortVal) {
|
||||||
|
this.shortVal = pShortVal;
|
||||||
public void setPintVal(int pintVal) {
|
}
|
||||||
this.pintVal = pintVal;
|
|
||||||
}
|
public Short getShortVal() {
|
||||||
|
return shortVal;
|
||||||
public int getPintVal() {
|
}
|
||||||
return pintVal;
|
|
||||||
}
|
public void setPintVal(int pintVal) {
|
||||||
|
this.pintVal = pintVal;
|
||||||
public void setIntVal(Integer intVal) {
|
}
|
||||||
this.intVal = intVal;
|
|
||||||
}
|
public int getPintVal() {
|
||||||
|
return pintVal;
|
||||||
public Integer getIntVal() {
|
}
|
||||||
return intVal;
|
|
||||||
}
|
public void setIntVal(Integer intVal) {
|
||||||
|
this.intVal = intVal;
|
||||||
public void setPlongVal(long plongVal) {
|
}
|
||||||
this.plongVal = plongVal;
|
|
||||||
}
|
public Integer getIntVal() {
|
||||||
|
return intVal;
|
||||||
public long getPlongVal() {
|
}
|
||||||
return plongVal;
|
|
||||||
}
|
public void setPlongVal(long plongVal) {
|
||||||
|
this.plongVal = plongVal;
|
||||||
public void setLongVal(Long longVal) {
|
}
|
||||||
this.longVal = longVal;
|
|
||||||
}
|
public long getPlongVal() {
|
||||||
|
return plongVal;
|
||||||
public Long getLongVal() {
|
}
|
||||||
return longVal;
|
|
||||||
}
|
public void setLongVal(Long longVal) {
|
||||||
|
this.longVal = longVal;
|
||||||
public void setPfloatVal(float pfloatVal) {
|
}
|
||||||
this.pfloatVal = pfloatVal;
|
|
||||||
}
|
public Long getLongVal() {
|
||||||
|
return longVal;
|
||||||
public float getPfloatVal() {
|
}
|
||||||
return pfloatVal;
|
|
||||||
}
|
public void setPfloatVal(float pfloatVal) {
|
||||||
|
this.pfloatVal = pfloatVal;
|
||||||
public void setFloatVal(Float floatVal) {
|
}
|
||||||
this.floatVal = floatVal;
|
|
||||||
}
|
public float getPfloatVal() {
|
||||||
|
return pfloatVal;
|
||||||
public Float getFloatVal() {
|
}
|
||||||
return floatVal;
|
|
||||||
}
|
public void setFloatVal(Float floatVal) {
|
||||||
|
this.floatVal = floatVal;
|
||||||
public void setPdblVal(double pdblVal) {
|
}
|
||||||
this.pdblVal = pdblVal;
|
|
||||||
}
|
public Float getFloatVal() {
|
||||||
|
return floatVal;
|
||||||
public double getPdblVal() {
|
}
|
||||||
return pdblVal;
|
|
||||||
}
|
public void setPdblVal(double pdblVal) {
|
||||||
|
this.pdblVal = pdblVal;
|
||||||
public void setDblVal(Double dblVal) {
|
}
|
||||||
this.dblVal = dblVal;
|
|
||||||
}
|
public double getPdblVal() {
|
||||||
|
return pdblVal;
|
||||||
public Double getDblVal() {
|
}
|
||||||
return dblVal;
|
|
||||||
}
|
public void setDblVal(Double dblVal) {
|
||||||
|
this.dblVal = dblVal;
|
||||||
public void setStringVal(String stringVal) {
|
}
|
||||||
this.stringVal = stringVal;
|
|
||||||
}
|
public Double getDblVal() {
|
||||||
|
return dblVal;
|
||||||
public String getStringVal() {
|
}
|
||||||
return stringVal;
|
|
||||||
}
|
public void setStringVal(String stringVal) {
|
||||||
|
this.stringVal = stringVal;
|
||||||
public void init() {
|
}
|
||||||
setPshortVal((short) 1);
|
|
||||||
setShortVal((short) 1);
|
public String getStringVal() {
|
||||||
setIntVal(1);
|
return stringVal;
|
||||||
setPintVal(1);
|
}
|
||||||
setLongVal(1L);
|
|
||||||
setPlongVal(1L);
|
public Date getUtilDate() {
|
||||||
setDblVal(1d);
|
return utilDate;
|
||||||
setPdblVal(1d);
|
}
|
||||||
setFloatVal(1f);
|
|
||||||
setPfloatVal(1f);
|
public void setUtilDate(Date utilDate) {
|
||||||
setStringVal("1");
|
this.utilDate = utilDate;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public java.sql.Date getSqlDate() {
|
||||||
|
return sqlDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSqlDate(java.sql.Date sqlDate) {
|
||||||
|
this.sqlDate = sqlDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
setPshortVal((short) 1);
|
||||||
|
setShortVal((short) 1);
|
||||||
|
setIntVal(1);
|
||||||
|
setPintVal(1);
|
||||||
|
setLongVal(1L);
|
||||||
|
setPlongVal(1L);
|
||||||
|
setDblVal(1d);
|
||||||
|
setPdblVal(1d);
|
||||||
|
setFloatVal(1f);
|
||||||
|
setPfloatVal(1f);
|
||||||
|
setStringVal("1");
|
||||||
|
setUtilDate(new java.util.Date());
|
||||||
|
setSqlDate(new java.sql.Date(getUtilDate().getTime()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -75,6 +75,9 @@ public class TestAggregateFunctions extends SingleEMFTestCase {
|
||||||
verifyResult(em, stringAggregateFunctions,
|
verifyResult(em, stringAggregateFunctions,
|
||||||
new String[] { "ae.stringVal" }, true, true);
|
new String[] { "ae.stringVal" }, true, true);
|
||||||
|
|
||||||
|
verifyResult(em, stringAggregateFunctions,
|
||||||
|
new String[]{"ae.utilDate", "ae.sqlDate"}, true, true);
|
||||||
|
|
||||||
// Add a row to the table and re-test
|
// Add a row to the table and re-test
|
||||||
AggEntity ae = new AggEntity();
|
AggEntity ae = new AggEntity();
|
||||||
ae.init();
|
ae.init();
|
||||||
|
@ -82,6 +85,8 @@ public class TestAggregateFunctions extends SingleEMFTestCase {
|
||||||
em.persist(ae);
|
em.persist(ae);
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
verifyResult(em, stringAggregateFunctions, "ae.sqlDate", java.sql.Date.class);
|
||||||
|
|
||||||
// Verify all numeric types for all aggregate functions return a
|
// Verify all numeric types for all aggregate functions return a
|
||||||
// non-null value when there is a query result
|
// non-null value when there is a query result
|
||||||
verifyResult(em, numericAggregateFunctions, numericAttributes, false);
|
verifyResult(em, numericAggregateFunctions, numericAttributes, false);
|
||||||
|
@ -90,6 +95,8 @@ public class TestAggregateFunctions extends SingleEMFTestCase {
|
||||||
verifyResult(em, stringAggregateFunctions,
|
verifyResult(em, stringAggregateFunctions,
|
||||||
new String[] { "ae.stringVal" }, false);
|
new String[] { "ae.stringVal" }, false);
|
||||||
|
|
||||||
|
verifyResult(em, stringAggregateFunctions, "ae.utilDate", java.util.Date.class);
|
||||||
|
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +248,21 @@ public class TestAggregateFunctions extends SingleEMFTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> void verifyResult(EntityManager em, String[] aggregates,
|
||||||
|
String attr, Class<T> expectedType) {
|
||||||
|
for (String func : aggregates) {
|
||||||
|
// JPQL with aggregate and aggregate in subselect
|
||||||
|
String sql = "SELECT " + func + "(" + attr + ")"
|
||||||
|
+ " FROM AggEntity ae WHERE " + attr + " <= "
|
||||||
|
+ "(SELECT " + func + "("
|
||||||
|
+ attr.replaceFirst("^ae.", "ae2.")
|
||||||
|
+ ") FROM AggEntity ae2)";
|
||||||
|
TypedQuery<T> q = em.createQuery(sql, expectedType);
|
||||||
|
T intance = q.getSingleResult();
|
||||||
|
assertEquals(intance.getClass(), expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyQueryResult(Query q, boolean emptyRs) {
|
private void verifyQueryResult(Query q, boolean emptyRs) {
|
||||||
verifyQueryResult(q, emptyRs, false);
|
verifyQueryResult(q, emptyRs, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue