-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ID data type mismatches in PostgreSQL #9
Comments
Not sure if this is the right solution, but something like this should do... randomf@bdd0187 |
Can you provide an example? The pojo, the insert, and the select that fail.
From: Radek Strnad
Sent: Tuesday, October 06, 2015 6:57 PM
To: dieselpoint/norm
Subject: [norm] ID data type mismatches in PostgreSQL (#9)
When inserting record to a table with ID defined as "serial" data type in PostgreSQL and having @id @GeneratedValue annotations on getter method in POJO, ID generated and returned by database is of Long type. However when I perform db.results() on the same class IDs are retrieved as Integer. This behaviour leads to type mismatch. Any idea how to approach the fix? Should we automatically convert Integers to Longs where possible and vice versa (if the value doesn't overflow)? Or is there better way?
—
Reply to this email directly or view it on GitHub.
|
Hello, please see the attached files. Let me know if you need more information on the problem. I added stack traces to the comments next to jUnit routines. I hope this helps... Thank you POJO package test;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "pojo")
public class NormPojo {
/** Database record ID. */
private Integer databaseId;
/** Unique identifier of the object. */
private String id;
/** Human readable name. */
private String name;
/**
* @return the id
*/
@Column(name = "object_id", unique = true)
public String getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
@Column(name = "name")
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
@Id
@GeneratedValue
@Column(name = "id")
public Integer getDatabaseId() {
return databaseId;
}
public void setDatabaseId(Integer databaseId) {
this.databaseId = databaseId;
}
} jUnit routines package test;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.dieselpoint.norm.Database;
public class NormPojoPersistenceTest {
static String DB_DRIVER_CLASS_NAME = "org.postgresql.ds.PGSimpleDataSource";
static String DB_SERVER_NAME = "localhost";
static String DB_DATABASE = "testdb";
static String DB_USERNAME = "testuser";
static String DB_PASSWORD = "testpass";
private Database db;
@Before
public void setUp() {
System.setProperty("norm.dataSourceClassName", DB_DRIVER_CLASS_NAME);
System.setProperty("norm.serverName", DB_SERVER_NAME);
System.setProperty("norm.databaseName", DB_DATABASE);
System.setProperty("norm.user", DB_USERNAME);
System.setProperty("norm.password", DB_PASSWORD);
db = new Database();
}
/*
* This test doesn't work when NormPojo.databaseId is of type Integer. However the record is inserted in the database.
*
* com.dieselpoint.norm.DbException: com.dieselpoint.norm.DbException: Could not write value into pojo. Property: id method: public void test.NormPojo.setDatabaseId(java.lang.Integer) value: 1
at com.dieselpoint.norm.sqlmakers.StandardSqlMaker.populateGeneratedKey(StandardSqlMaker.java:356)
at com.dieselpoint.norm.Query.execute(Query.java:339)
at com.dieselpoint.norm.Query.insert(Query.java:256)
at com.dieselpoint.norm.Database.insert(Database.java:109)
at test.NormPojoPersistenceTest.testCreate(NormPojoPersistenceTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: com.dieselpoint.norm.DbException: Could not write value into pojo. Property: id method: public void test.NormPojo.setDatabaseId(java.lang.Integer) value: 1
at com.dieselpoint.norm.sqlmakers.StandardPojoInfo.putValue(StandardPojoInfo.java:257)
at com.dieselpoint.norm.sqlmakers.StandardSqlMaker.populateGeneratedKey(StandardSqlMaker.java:353)
... 28 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.dieselpoint.norm.sqlmakers.StandardPojoInfo.putValue(StandardPojoInfo.java:254)
... 29 more
*/
@Test
public void testCreate() {
NormPojo np = new NormPojo();
np.setId("MyID");
np.setName("My name");
db.insert(np);
Assert.assertNotNull(np.getDatabaseId());
}
/*
* Test test runs correctly when NormPojo.databaseId is of type Integer.
*
* However when changing NormPojo.databaseId to type Long, following exception is thrown:
* com.dieselpoint.norm.DbException: Could not write value into pojo. Property: id method: public void test.NormPojo.setDatabaseId(java.lang.Long) value: 1
at com.dieselpoint.norm.sqlmakers.StandardPojoInfo.putValue(StandardPojoInfo.java:257)
at com.dieselpoint.norm.Query.results(Query.java:207)
at com.dieselpoint.norm.Database.results(Database.java:128)
at test.NormPojoPersistenceTest.testRetrieval(NormPojoPersistenceTest.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.dieselpoint.norm.sqlmakers.StandardPojoInfo.putValue(StandardPojoInfo.java:254)
... 27 more
*/
@Test
public void testRetrieval() {
List<NormPojo> npList = null;
npList = db.results(NormPojo.class);
Assert.assertNotNull(npList);
Assert.assertTrue(npList.size() > 0);
}
} Schema CREATE TABLE pojo (
id serial,
object_id varchar(128) NOT NULL,
name varchar(128) NOT NULL,
CONSTRAINT pk PRIMARY KEY (id)
); pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>norm</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.dieselpoint</groupId>
<artifactId>norm</artifactId>
<version>0.8.1-rc2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1201-jdbc41</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project> |
I can confirm the issue on H2 database. |
The check if the filed is an int or Integer should be like this:
|
Fixed. Sorry it took so long. Will be in today's release. |
When inserting record to a table with ID defined as "serial" data type in PostgreSQL and having @id @GeneratedValue annotations on getter method in POJO, ID generated and returned by database is of Long type. However when I perform db.results() on the same class IDs are retrieved as Integer. This behaviour leads to type mismatch. Any idea how to approach the fix? Should we automatically convert Integers to Longs where possible and vice versa (if the value doesn't overflow)? Or is there better way?
The text was updated successfully, but these errors were encountered: