@RegisterMapper(PhoneNumberMapper.class)
public interface PhoneNumberJdbiDAO
{
@Transaction
@GetGeneratedKeys(columnName = "ID", value = OracleGeneratedKeyMapper.class)
@SqlUpdate("INSERT INTO PHONE_NUMBER (ID, COUNTRY_CODE_ISO2, PHONE_NUMBER, CREATE_DATETIME, UPDATE_DATETIME) " +
"VALUES (PHONE_NUMBER_SEQ.NEXTVAL, :countryCode, :phoneNumber, :createDateTime, :updateDateTime)")
PhoneNumber save(@BindBean PhoneNumber phoneNumber);
}
Can the OracleGeneratedKeyMapper.class
and PhoneNumberMapper.class
co-exist to return the mapped bean? When I execute this, java.lang.ClassCastException: java.math.BigDecimal cannot be cast to me.nave.persistence.domain.PhoneNumber
is being thrown.
The intent is to return a bean with the generated ID.
The PhoneNumberMapper
public class PhoneNumberMapper implements org.skife.jdbi.v2.tweak.ResultSetMapper<PhoneNumber>
{
@Override
public PhoneNumber map(int index, ResultSet rs, StatementContext ctx) throws SQLException
{
CountryCode countryCodeIso2 = CountryCode.getByCodeIgnoreCase(rs.getString("COUNTRY_CODE_ISO2"));
DateTime phoneNumberCreateDatetime =
new DateTime(rs.getTimestamp("CREATE_DATETIME").getTime(), DateTimeZone.UTC);
DateTime phoneNumberUpdateDatetime =
new DateTime(rs.getTimestamp("UPDATE_DATETIME").getTime(), DateTimeZone.UTC);
return new PhoneNumber
.Builder(countryCodeIso2, rs.getString("PHONE_NUMBER"))
.id(rs.getBigDecimal("ID"))
.createDateTime(phoneNumberCreateDatetime)
.updateDateTime(phoneNumberUpdateDatetime)
.build();
}
}
Here is the OracleGeneratedKeyMapper.
public class OracleGeneratedKeyMapper implements org.skife.jdbi.v2.tweak.ResultSetMapper<BigDecimal>
{
@Override
public BigDecimal map(int index, ResultSet r, StatementContext ctx) throws SQLException
{
return r.getBigDecimal(1);
}
}
The table and Sequences
CREATE SEQUENCE "PHONE_NUMBER_SEQ" MINVALUE 1 INCREMENT BY 1;
CREATE TABLE "TEST"."PHONE_NUMBER"
( "ID" NUMBER NOT NULL,
"COUNTRY_CODE_ISO2" VARCHAR2(2 CHAR) NOT NULL,
"PHONE_NUMBER" VARCHAR2(32 CHAR) NOT NULL,
"CREATE_DATETIME" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP(0) NOT NULL,
"UPDATE_DATETIME" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP(0) NOT NULL,
CONSTRAINT "PHONE_NUMBER_PK" PRIMARY KEY ("ID")
);
@Mapper and @RegisterMapper is not used while getting inserted id back. If you want PhoneNumber object (with id alone) to be returned after insert, You can use following mapper.
public class PhoneNumberIdMapper implements org.skife.jdbi.v2.tweak.ResultSetMapper<BigDecimal>
{
@Override
public BigDecimal map(int index, ResultSet r, StatementContext ctx) throws SQLException
{
return new PhoneNumber(r.getBigDecimal(1));
}
}
But if you are looking to get the whole PhoneNumber object, we need to do it manually. I could think of two options,
public abstract PhoneNumber savePhoneNumber(PhoneNumber phoneNumber) {
BigDecimal id = save(phoneNumber);
phoneNumber.setId(id)
}
Or read it from DB again.
public abstract PhoneNumber savePhoneNumber(PhoneNumber phoneNumber) {
BigDecimal id = save(phoneNumber);
getPhoneNumber(id); // reading it from DB
}