Merge pull request #5655 from asturcon/string-cast-jpa
BAEL-2239 - JPA error "java.lang.String cannot be cast to [Ljava.lang.String;"
This commit is contained in:
commit
f92c0f8794
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.jpa.stringcast;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
@SqlResultSetMapping(name = "textQueryMapping", classes = {
|
||||||
|
@ConstructorResult(targetClass = DummyEntity.class, columns = {
|
||||||
|
@ColumnResult(name = "text")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
@Entity
|
||||||
|
@Table(name = "dummy")
|
||||||
|
public class DummyEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public DummyEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public DummyEntity(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.jpa.stringcast;
|
||||||
|
|
||||||
|
import com.sun.istack.internal.Nullable;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.Query;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class QueryExecutor {
|
||||||
|
|
||||||
|
public static List<String[]> executeNativeQueryNoCastCheck(String statement, EntityManager em) {
|
||||||
|
Query query = em.createNativeQuery(statement);
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String[]> executeNativeQueryWithCastCheck(String statement, EntityManager em) {
|
||||||
|
Query query = em.createNativeQuery(statement);
|
||||||
|
List results = query.getResultList();
|
||||||
|
|
||||||
|
if (results.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.get(0) instanceof String) {
|
||||||
|
return ((List<String>) results)
|
||||||
|
.stream()
|
||||||
|
.map(s -> new String[] { s })
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
return (List<String[]>) results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> executeNativeQueryGeneric(String statement, String mapping, EntityManager em) {
|
||||||
|
Query query = em.createNativeQuery(statement, mapping);
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,6 +20,21 @@
|
||||||
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="jpa-h2">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
<class>com.baeldung.jpa.stringcast.DummyEntity</class>
|
||||||
|
<properties>
|
||||||
|
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
|
||||||
|
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
|
||||||
|
<property name="javax.persistence.jdbc.user" value="sa" />
|
||||||
|
<property name="javax.persistence.jdbc.password" value="" />
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||||
|
<property name="show_sql" value="true"/>
|
||||||
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
<persistence-unit name="jpa-db">
|
<persistence-unit name="jpa-db">
|
||||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.jpa.stringcast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class SpringCastUnitTest {
|
||||||
|
|
||||||
|
private static EntityManager em;
|
||||||
|
private static EntityManagerFactory emFactory;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
emFactory = Persistence.createEntityManagerFactory("jpa-h2");
|
||||||
|
em = emFactory.createEntityManager();
|
||||||
|
|
||||||
|
// insert an object into the db
|
||||||
|
DummyEntity dummyEntity = new DummyEntity();
|
||||||
|
dummyEntity.setText("text");
|
||||||
|
|
||||||
|
EntityTransaction tr = em.getTransaction();
|
||||||
|
tr.begin();
|
||||||
|
em.persist(dummyEntity);
|
||||||
|
tr.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenExecutorNoCastCheck_whenQueryReturnsOneColumn_thenClassCastThrown() {
|
||||||
|
List<String[]> results = QueryExecutor.executeNativeQueryNoCastCheck("select text from dummy", em);
|
||||||
|
|
||||||
|
// fails
|
||||||
|
for (String[] row : results) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExecutorWithCastCheck_whenQueryReturnsOneColumn_thenNoClassCastThrown() {
|
||||||
|
List<String[]> results = QueryExecutor.executeNativeQueryWithCastCheck("select text from dummy", em);
|
||||||
|
assertEquals("text", results.get(0)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExecutorGeneric_whenQueryReturnsOneColumn_thenNoClassCastThrown() {
|
||||||
|
List<DummyEntity> results = QueryExecutor.executeNativeQueryGeneric("select text from dummy", "textQueryMapping", em);
|
||||||
|
assertEquals("text", results.get(0).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,5 +17,21 @@
|
||||||
<property name="hibernate.show_sql" value="true" />
|
<property name="hibernate.show_sql" value="true" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="jpa-h2">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
<class>com.baeldung.jpa.stringcast.DummyEntity</class>
|
||||||
|
<properties>
|
||||||
|
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
|
||||||
|
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
|
||||||
|
<property name="javax.persistence.jdbc.user" value="sa" />
|
||||||
|
<property name="javax.persistence.jdbc.password" value="" />
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||||
|
<property name="show_sql" value="true"/>
|
||||||
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
</persistence>
|
</persistence>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue