diff --git a/jOOQ-test/src/org/jooq/test/_/IBookWithAnnotations.java b/jOOQ-test/src/org/jooq/test/_/IBookWithAnnotations.java new file mode 100644 index 0000000000..5495416444 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/_/IBookWithAnnotations.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq.test._; + +import javax.persistence.Column; + +/** + * @author Lukas Eder + */ +public interface IBookWithAnnotations { + + // Methods with annotations + // ------------------------ + @Column(name = "ID") + public void setId(long id); + + @Column(name = "ID") + public void setId(Long id); + + public long getId(); + + @Column(name = "FIRST_NAME") + public void setFirstName(String f); + + @Column(name = "LAST_NAME") + public void setLastName(String l); + + public void setLAST_NAME(String l); + + @Column(name = "LAST_NAME") + public String getLAST_NAME(); + + @Column(name = "LAST_NAME") + public void tooManyParameters(String l, String tooMany); + + @Column(name = "LAST_NAME") + public void notEnoughParameters(); +} diff --git a/jOOQ-test/src/org/jooq/test/_/IBookWithoutAnnotations.java b/jOOQ-test/src/org/jooq/test/_/IBookWithoutAnnotations.java new file mode 100644 index 0000000000..a7cc8853c3 --- /dev/null +++ b/jOOQ-test/src/org/jooq/test/_/IBookWithoutAnnotations.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com + * All rights reserved. + * + * This software is licensed to you under the Apache License, Version 2.0 + * (the "License"); You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name "jOOQ" nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package org.jooq.test._; + + +/** + * @author Lukas Eder + */ +public interface IBookWithoutAnnotations { + + public void setId(long id); + public long getId(); + public void setFirstName(String f); + public void setLAST_NAME(String l); + public String getLAST_NAME(); + public void setLAST_NAME(String l, String tooManyParameters); + public void setLAST_NAME(); +} diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java index 109250ae53..c42ef2a65e 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java @@ -67,6 +67,7 @@ import org.jooq.Field; import org.jooq.Record; import org.jooq.RecordHandler; import org.jooq.Result; +import org.jooq.Select; import org.jooq.SelectQuery; import org.jooq.TableRecord; import org.jooq.UpdatableRecord; @@ -83,6 +84,8 @@ import org.jooq.test._.CharWithAnnotations; import org.jooq.test._.DatesWithAnnotations; import org.jooq.test._.FinalWithAnnotations; import org.jooq.test._.FinalWithoutAnnotations; +import org.jooq.test._.IBookWithAnnotations; +import org.jooq.test._.IBookWithoutAnnotations; import org.jooq.test._.ImmutableAuthor; import org.jooq.test._.StaticWithAnnotations; import org.jooq.test._.StaticWithoutAnnotations; @@ -296,7 +299,7 @@ extends BaseTest result = + Select select = create().select( TBook_ID(), TBook_TITLE(), @@ -305,60 +308,73 @@ extends BaseTest result1 = select.fetchInto(BookWithAnnotations.class); + List result2 = select.fetchInto(IBookWithAnnotations.class); - assertEquals(1, (int) result.get(0).id); - assertEquals(2, (int) result.get(1).id); - assertEquals(3, (int) result.get(2).id); - assertEquals(4, (int) result.get(3).id); + assertEquals(4, result1.size()); + assertEquals(4, result2.size()); - assertEquals(1, result.get(0).id2); - assertEquals(2, result.get(1).id2); - assertEquals(3, result.get(2).id2); - assertEquals(4, result.get(3).id2); + assertEquals(1, (int) result1.get(0).id); + assertEquals(2, (int) result1.get(1).id); + assertEquals(3, (int) result1.get(2).id); + assertEquals(4, (int) result1.get(3).id); - assertEquals(1, result.get(0).id3); - assertEquals(2, result.get(1).id3); - assertEquals(3, result.get(2).id3); - assertEquals(4, result.get(3).id3); + assertEquals(1, result1.get(0).id2); + assertEquals(2, result1.get(1).id2); + assertEquals(3, result1.get(2).id2); + assertEquals(4, result1.get(3).id2); - assertEquals(Long.valueOf(1), result.get(0).id4); - assertEquals(Long.valueOf(2), result.get(1).id4); - assertEquals(Long.valueOf(3), result.get(2).id4); - assertEquals(Long.valueOf(4), result.get(3).id4); + assertEquals(1, result1.get(0).id3); + assertEquals(2, result1.get(1).id3); + assertEquals(3, result1.get(2).id3); + assertEquals(4, result1.get(3).id3); - assertEquals(1L, result.get(0).id5); - assertEquals(2L, result.get(1).id5); - assertEquals(3L, result.get(2).id5); - assertEquals(4L, result.get(3).id5); + assertEquals(Long.valueOf(1), result1.get(0).id4); + assertEquals(Long.valueOf(2), result1.get(1).id4); + assertEquals(Long.valueOf(3), result1.get(2).id4); + assertEquals(Long.valueOf(4), result1.get(3).id4); - assertEquals("1984", result.get(0).title); - assertEquals("Animal Farm", result.get(1).title); - assertEquals("O Alquimista", result.get(2).title); - assertEquals("Brida", result.get(3).title); + assertEquals(1L, result1.get(0).id5); + assertEquals(2L, result1.get(1).id5); + assertEquals(3L, result1.get(2).id5); + assertEquals(4L, result1.get(3).id5); - assertEquals("George", result.get(0).firstName); - assertEquals("George", result.get(1).firstName); - assertEquals("Paulo", result.get(2).firstName); - assertEquals("Paulo", result.get(3).firstName); + assertEquals(1, (int) result2.get(0).getId()); + assertEquals(2, (int) result2.get(1).getId()); + assertEquals(3, (int) result2.get(2).getId()); + assertEquals(4, (int) result2.get(3).getId()); - assertEquals("George", result.get(0).firstName2); - assertEquals("George", result.get(1).firstName2); - assertEquals("Paulo", result.get(2).firstName2); - assertEquals("Paulo", result.get(3).firstName2); + assertEquals("1984", result1.get(0).title); + assertEquals("Animal Farm", result1.get(1).title); + assertEquals("O Alquimista", result1.get(2).title); + assertEquals("Brida", result1.get(3).title); - assertEquals("Orwell", result.get(0).lastName); - assertEquals("Orwell", result.get(1).lastName); - assertEquals("Coelho", result.get(2).lastName); - assertEquals("Coelho", result.get(3).lastName); + assertEquals("George", result1.get(0).firstName); + assertEquals("George", result1.get(1).firstName); + assertEquals("Paulo", result1.get(2).firstName); + assertEquals("Paulo", result1.get(3).firstName); - assertEquals("Orwell", result.get(0).lastName2); - assertEquals("Orwell", result.get(1).lastName2); - assertEquals("Coelho", result.get(2).lastName2); - assertEquals("Coelho", result.get(3).lastName2); + assertEquals("George", result1.get(0).firstName2); + assertEquals("George", result1.get(1).firstName2); + assertEquals("Paulo", result1.get(2).firstName2); + assertEquals("Paulo", result1.get(3).firstName2); + + assertEquals("Orwell", result1.get(0).lastName); + assertEquals("Orwell", result1.get(1).lastName); + assertEquals("Coelho", result1.get(2).lastName); + assertEquals("Coelho", result1.get(3).lastName); + + assertEquals("Orwell", result1.get(0).lastName2); + assertEquals("Orwell", result1.get(1).lastName2); + assertEquals("Coelho", result1.get(2).lastName2); + assertEquals("Coelho", result1.get(3).lastName2); + + assertEquals("Orwell", result2.get(0).getLAST_NAME()); + assertEquals("Orwell", result2.get(1).getLAST_NAME()); + assertEquals("Coelho", result2.get(2).getLAST_NAME()); + assertEquals("Coelho", result2.get(3).getLAST_NAME()); try { // Cannot instanciate an abstract class @@ -447,7 +463,7 @@ extends BaseTest result = + Select select = create().select( TBook_ID(), TBook_TITLE(), @@ -456,55 +472,68 @@ extends BaseTest result1 = select.fetchInto(BookWithoutAnnotations.class); + List result2 = select.fetchInto(IBookWithoutAnnotations.class); - assertEquals(1, (int) result.get(0).id); - assertEquals(2, (int) result.get(1).id); - assertEquals(3, (int) result.get(2).id); - assertEquals(4, (int) result.get(3).id); + assertEquals(4, result1.size()); + assertEquals(4, result2.size()); - assertEquals(1, result.get(0).id2); - assertEquals(2, result.get(1).id2); - assertEquals(3, result.get(2).id2); - assertEquals(4, result.get(3).id2); + assertEquals(1, (int) result1.get(0).id); + assertEquals(2, (int) result1.get(1).id); + assertEquals(3, (int) result1.get(2).id); + assertEquals(4, (int) result1.get(3).id); - assertEquals(1, result.get(0).ID); - assertEquals(2, result.get(1).ID); - assertEquals(3, result.get(2).ID); - assertEquals(4, result.get(3).ID); + assertEquals(1, result1.get(0).id2); + assertEquals(2, result1.get(1).id2); + assertEquals(3, result1.get(2).id2); + assertEquals(4, result1.get(3).id2); - assertEquals("1984", result.get(0).title); - assertEquals("Animal Farm", result.get(1).title); - assertEquals("O Alquimista", result.get(2).title); - assertEquals("Brida", result.get(3).title); + assertEquals(1, result1.get(0).ID); + assertEquals(2, result1.get(1).ID); + assertEquals(3, result1.get(2).ID); + assertEquals(4, result1.get(3).ID); - assertEquals("George", result.get(0).firstName); - assertEquals("George", result.get(1).firstName); - assertEquals("Paulo", result.get(2).firstName); - assertEquals("Paulo", result.get(3).firstName); + assertEquals(1, (int) result2.get(0).getId()); + assertEquals(2, (int) result2.get(1).getId()); + assertEquals(3, (int) result2.get(2).getId()); + assertEquals(4, (int) result2.get(3).getId()); - assertEquals("George", result.get(0).firstName2); - assertEquals("George", result.get(1).firstName2); - assertEquals("Paulo", result.get(2).firstName2); - assertEquals("Paulo", result.get(3).firstName2); + assertEquals("1984", result1.get(0).title); + assertEquals("Animal Farm", result1.get(1).title); + assertEquals("O Alquimista", result1.get(2).title); + assertEquals("Brida", result1.get(3).title); - assertEquals("Orwell", result.get(0).lastName); - assertEquals("Orwell", result.get(1).lastName); - assertEquals("Coelho", result.get(2).lastName); - assertEquals("Coelho", result.get(3).lastName); + assertEquals("George", result1.get(0).firstName); + assertEquals("George", result1.get(1).firstName); + assertEquals("Paulo", result1.get(2).firstName); + assertEquals("Paulo", result1.get(3).firstName); - assertEquals("Orwell", result.get(0).lastName2); - assertEquals("Orwell", result.get(1).lastName2); - assertEquals("Coelho", result.get(2).lastName2); - assertEquals("Coelho", result.get(3).lastName2); + assertEquals("George", result1.get(0).firstName2); + assertEquals("George", result1.get(1).firstName2); + assertEquals("Paulo", result1.get(2).firstName2); + assertEquals("Paulo", result1.get(3).firstName2); - assertEquals("Orwell", result.get(0).LAST_NAME); - assertEquals("Orwell", result.get(1).LAST_NAME); - assertEquals("Coelho", result.get(2).LAST_NAME); - assertEquals("Coelho", result.get(3).LAST_NAME); + assertEquals("Orwell", result1.get(0).lastName); + assertEquals("Orwell", result1.get(1).lastName); + assertEquals("Coelho", result1.get(2).lastName); + assertEquals("Coelho", result1.get(3).lastName); + + assertEquals("Orwell", result1.get(0).lastName2); + assertEquals("Orwell", result1.get(1).lastName2); + assertEquals("Coelho", result1.get(2).lastName2); + assertEquals("Coelho", result1.get(3).lastName2); + + assertEquals("Orwell", result1.get(0).LAST_NAME); + assertEquals("Orwell", result1.get(1).LAST_NAME); + assertEquals("Coelho", result1.get(2).LAST_NAME); + assertEquals("Coelho", result1.get(3).LAST_NAME); + + assertEquals("Orwell", result2.get(0).getLAST_NAME()); + assertEquals("Orwell", result2.get(1).getLAST_NAME()); + assertEquals("Coelho", result2.get(2).getLAST_NAME()); + assertEquals("Coelho", result2.get(3).getLAST_NAME()); } @Test diff --git a/jOOQ/src/main/java/org/jooq/Record.java b/jOOQ/src/main/java/org/jooq/Record.java index 4020e872f8..7c37458f88 100644 --- a/jOOQ/src/main/java/org/jooq/Record.java +++ b/jOOQ/src/main/java/org/jooq/Record.java @@ -37,17 +37,20 @@ package org.jooq; import java.lang.reflect.Constructor; +import java.lang.reflect.Proxy; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; +import java.util.HashMap; import javax.persistence.Column; import org.jooq.exception.DataTypeException; import org.jooq.exception.MappingException; import org.jooq.tools.Convert; +import org.jooq.tools.reflect.Reflect; /** * A wrapper for database result records returned by @@ -1170,6 +1173,12 @@ public interface Record extends FieldProvider, Store { * chosen (as reported by {@link Class#getDeclaredConstructors()} *
  • When invoking the "matching" * + *

    If the supplied type is an interface or an abstract class

    + * Abstract types are instanciated using Java reflection {@link Proxy} + * mechanisms. The returned proxy will wrap a {@link HashMap} containing + * properties mapped by getters and setters of the supplied type. Methods + * (even JPA-annotated ones) other than standard POJO getters and setters + * are not supported. Details can be seen in {@link Reflect#as(Class)}. *

    Other restrictions

    *
      *
    • type must provide a default or a "matching" constructor. diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java index 8c448f0480..a13b619bbc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java @@ -55,6 +55,7 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import org.jooq.ArrayRecord; @@ -619,9 +620,18 @@ abstract class AbstractRecord extends AbstractStore implements Record { // If a default, no argument constructor is present, use that one. try { + T result; + + // [#1470] Return a proxy if the supplied type is an interface + if (Modifier.isAbstract(type.getModifiers())) { + result = Reflect.on(HashMap.class).create().as(type); + } // [#1340] Allow for using non-public default constructors - T result = Reflect.accessible(type.getDeclaredConstructor()).newInstance(); + else { + result = Reflect.accessible(type.getDeclaredConstructor()).newInstance(); + } + return intoMutablePOJO(type, result); }