mirror of https://github.com/apache/openjpa.git
OPENJPA-2651: Fix for issue where @SqlResultSetMapping is used with inheritance and a ManyToOne relationship. Merged 2.2.x commit to trunk.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1756047 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
41827d794d
commit
4afdb07042
|
@ -404,6 +404,20 @@ class MappedQueryResultObjectProvider
|
|||
return _res.getLong((Column) obj, joins);
|
||||
return _res.getLong(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* OPENJPA-2651: Added to allow the column to be translated (from the
|
||||
* actual column name to the name provided in an @SqlResultSetMapping/@FieldResult.
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see org.apache.openjpa.jdbc.sql.AbstractResult#getObject(org.apache.
|
||||
* openjpa.jdbc.schema.Column, java.lang.Object, org.apache.openjpa.jdbc.sql.Joins)
|
||||
*/
|
||||
public Object getObject(Column col, Object arg, Joins joins)
|
||||
throws SQLException {
|
||||
return getObjectInternal(translate(col, joins), col.getJavaType(),
|
||||
arg, joins);
|
||||
}
|
||||
|
||||
protected Object getObjectInternal(Object obj, int metaTypeCode,
|
||||
Object arg, Joins joins)
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.query.sqlresultmapping;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@javax.persistence.Table(name = "CRT_OPERACAO")
|
||||
@Entity
|
||||
public class CrtOperacaoEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3914425448077243671L;
|
||||
|
||||
@Column(name = "ID")
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Column(name = "DATA_HORA")
|
||||
private Timestamp dataHora;
|
||||
|
||||
public Timestamp getDataHora() {
|
||||
return this.dataHora;
|
||||
}
|
||||
|
||||
public void setDataHora(final Timestamp dataHora) {
|
||||
this.dataHora = dataHora;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.query.sqlresultmapping;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityResult;
|
||||
import javax.persistence.FieldResult;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.SqlResultSetMapping;
|
||||
|
||||
@javax.persistence.Table(name = "CRT_REQUISICAO_CHEQUE_PERS")
|
||||
@Entity
|
||||
@SqlResultSetMapping(name = "MyResultMapping", entities = {
|
||||
@EntityResult(entityClass = CrtRequisicaoChequePersEntity.class, fields = {
|
||||
@FieldResult(name = "crtOperacaoByOperacaoRecepcaoServCent.id",
|
||||
column = "opRecepcaoServCentraisId"),
|
||||
@FieldResult(name = "crtOperacaoByOperacaoRecepcaoServCent.dataHora",
|
||||
column = "opRecepcaoServCentraisDataHora") }) })
|
||||
public class CrtRequisicaoChequePersEntity extends CrtRequisicaoEntity {
|
||||
|
||||
@ManyToOne
|
||||
@javax.persistence.JoinColumn(name = "OPERACAO_RECEPCAO_SERV_CENT", referencedColumnName = "ID")
|
||||
private CrtOperacaoEntity crtOperacaoByOperacaoRecepcaoServCent;
|
||||
|
||||
public CrtOperacaoEntity getCrtOperacaoByOperacaoRecepcaoServCent() {
|
||||
return this.crtOperacaoByOperacaoRecepcaoServCent;
|
||||
}
|
||||
|
||||
public void setCrtOperacaoByOperacaoRecepcaoServCent(
|
||||
final CrtOperacaoEntity crtOperacaoByOperacaoRecepcaoServCent) {
|
||||
this.crtOperacaoByOperacaoRecepcaoServCent =
|
||||
crtOperacaoByOperacaoRecepcaoServCent;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@javax.persistence.JoinColumn(name = "OPERACAO_REQUISICAO", referencedColumnName = "ID", nullable = false)
|
||||
private CrtOperacaoEntity crtOperacaoByOperacaoRequisicao;
|
||||
|
||||
public CrtOperacaoEntity getCrtOperacaoByOperacaoRequisicao() {
|
||||
return this.crtOperacaoByOperacaoRequisicao;
|
||||
}
|
||||
|
||||
public void setCrtOperacaoByOperacaoRequisicao(
|
||||
final CrtOperacaoEntity crtOperacaoByOperacaoRequisicao) {
|
||||
this.crtOperacaoByOperacaoRequisicao = crtOperacaoByOperacaoRequisicao;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.query.sqlresultmapping;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
@javax.persistence.Table(name = "CRT_REQUISICAO")
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public class CrtRequisicaoEntity {
|
||||
@Column(name = "ID")
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.persistence.query.sqlresultmapping;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.openjpa.persistence.querycache.QCEntity;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
/*
|
||||
* Test for OPENJPA-2651.
|
||||
*/
|
||||
public class TestSQLResultSetMapping extends SingleEMFTestCase {
|
||||
|
||||
public void setUp() {
|
||||
super.setUp(DROP_TABLES, CrtOperacaoEntity.class,
|
||||
CrtRequisicaoEntity.class, CrtRequisicaoChequePersEntity.class);
|
||||
|
||||
// Set up necessary test data:
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
CrtOperacaoEntity op = new CrtOperacaoEntity();
|
||||
op.setId(25384);
|
||||
op.setDataHora(Timestamp.valueOf("2014-12-16 15:24:54.0"));
|
||||
em.persist(op);
|
||||
|
||||
CrtOperacaoEntity op2 = new CrtOperacaoEntity();
|
||||
op2.setId(23409);
|
||||
op2.setDataHora(Timestamp.valueOf("2014-10-27 16:12:53.0"));
|
||||
em.persist(op2);
|
||||
|
||||
CrtRequisicaoChequePersEntity reqCheq =
|
||||
new CrtRequisicaoChequePersEntity();
|
||||
reqCheq.setId(500006164);
|
||||
reqCheq.setCrtOperacaoByOperacaoRecepcaoServCent(op);
|
||||
reqCheq.setCrtOperacaoByOperacaoRequisicao(op2);
|
||||
em.persist(reqCheq);
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Prior to OPENJPA-2651, this test would result in the following exception:
|
||||
*
|
||||
* PersistenceException: Column '0' not found.
|
||||
* FailedObject:
|
||||
* org.apache.openjpa.persistence.query.sqlresultmapping.CrtOperacaoEntity-500006164 [java.lang.String]
|
||||
* at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4998)
|
||||
* .....
|
||||
* Caused by: java.sql.SQLException: Column '0' not found.
|
||||
*/
|
||||
public void testMappingNoException() {
|
||||
|
||||
String sql = "SELECT t0.ID, t2.DATA_HORA as opRecepcaoServCentraisDataHora, t2.ID as opRecepcaoServCentraisId"
|
||||
+ " FROM CRT_REQUISICAO_CHEQUE_PERS t0, CRT_OPERACAO t2 WHERE t0.ID = 500006164 and t2.ID = 25384";
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
Query query = em.createNativeQuery(sql, "MyResultMapping");
|
||||
List<CrtRequisicaoChequePersEntity> res = query.getResultList();
|
||||
|
||||
assertEquals(res.size(), 1);
|
||||
assertEquals(500006164, res.get(0).getId());
|
||||
assertEquals(25384, res.get(0).getCrtOperacaoByOperacaoRecepcaoServCent().getId());
|
||||
assertEquals(Timestamp.valueOf("2014-12-16 15:24:54.0"),
|
||||
res.get(0).getCrtOperacaoByOperacaoRecepcaoServCent().getDataHora());
|
||||
|
||||
em.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Prior to OPENJPA-2651, this test would result in the wrong id provided in the
|
||||
* CrtOperacaoEntity. Specifically, the ID in CrtOperacaoEntity would contain
|
||||
* '500006164', which is the ID for the CrtRequisicaoEntity.
|
||||
*/
|
||||
public void testMappingCorrectID() {
|
||||
|
||||
String sql =
|
||||
"SELECT t0.ID, t1.ID as opRecepcaoServCentraisId, t1.DATA_HORA as opRecepcaoServCentraisDataHora, "
|
||||
+ "t2.ID, t2.DATA_HORA, t3.ID, t4.ID, t4.OPERACAO_RECEPCAO_SERV_CENT, "
|
||||
+ "t4.OPERACAO_REQUISICAO FROM CRT_REQUISICAO_CHEQUE_PERS t0 LEFT OUTER JOIN "
|
||||
+ "CRT_OPERACAO t1 ON t0.OPERACAO_RECEPCAO_SERV_CENT = t1.ID LEFT OUTER JOIN "
|
||||
+ "CRT_OPERACAO t2 ON t0.OPERACAO_REQUISICAO = t2.ID "
|
||||
+ "LEFT OUTER JOIN CRT_REQUISICAO t3 "
|
||||
+ "ON t0.ID = t3.ID INNER JOIN CRT_REQUISICAO t5 "
|
||||
+ "ON t0.ID = t5.ID LEFT OUTER JOIN "
|
||||
+ "CRT_REQUISICAO_CHEQUE_PERS t4 "
|
||||
+ "ON t3.ID = t4.ID WHERE t0.ID = 500006164";
|
||||
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
Query query = em.createNativeQuery(sql, "MyResultMapping");
|
||||
List<CrtRequisicaoChequePersEntity> res = query.getResultList();
|
||||
|
||||
assertEquals(res.size(), 1);
|
||||
assertEquals(500006164, res.get(0).getId());
|
||||
assertEquals(25384, res.get(0).getCrtOperacaoByOperacaoRecepcaoServCent().getId());
|
||||
assertEquals(Timestamp.valueOf("2014-12-16 15:24:54.0"),
|
||||
res.get(0).getCrtOperacaoByOperacaoRecepcaoServCent().getDataHora());
|
||||
|
||||
em.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue