Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jooq CustomTypes generating default type POJOs

Tags:

java

sql

jooq

Trying to generate JooQ POJOs with Joda DateTimes, and am having some issues. The POJOs come out of the generator with default java.sql.TimeStamp values, not DateTimes.

Code below.

Create Table -- name of the timestamp field here was changed -- wanted to ensure I wasn't hitting a cache somewhere in my build system. This name should still work with the below regex for matching.

CREATE TABLE nonsense (
  name VARCHAR(50) NOT NULL,
  DATETIME_TEST TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  id UUID NOT NULL,
  PRIMARY KEY(id)
);

Conversion class -- Based on the documentation.

public class LocalDateTimeConverter implements Converter<Timestamp, LocalDateTime> {

    @Override
    public LocalDateTime from(Timestamp databaseObject) {
        return new LocalDateTime(databaseObject.getTime());
    }

    @Override
    public Timestamp to(LocalDateTime dt) {
        return new Timestamp(dt.toDateTime().getMillis());
    }

    @Override
    public Class<Timestamp> fromType() {
        return Timestamp.class;
    }

    @Override
    public Class<LocalDateTime> toType() {
        return LocalDateTime.class;
    }
}

Jooq configuration XML. Based on documentation (thanks for catching my expression/expressions error Luke)!

<configuration>
  <generator>
    <database>
      <customTypes>
        <customType>
          <name>org.joda.time.LocalDateTime</name>
          <converter>n.b.jooqJodaTime.LocalDateTimeConverter</converter>
        </customType>
      </customTypes>
      <forcedtypes>
        <forcedType>
          <name>org.joda.time.LocalDateTime</name>
          <expressions>.*DATETIME.*</expressions>
        </forcedType>
      </forcedtypes>
    </database>
  </generator>
</configuration>

Created POJO:

@javax.persistence.Column(name = "DATETIME_TEST", precision = 23, scale = 10)
public java.sql.Timestamp getDatetimeTest() {
    return this.datetimeTest;
}

For historical context, this was the original question.


Create Table:

CREATE TABLE nonsense (
  name VARCHAR(50) NOT NULL,
  TEST_DATETIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  id UUID NOT NULL,
  PRIMARY KEY(id)
);

Converter:

package n.b.jooqJodaTime;

import org.joda.time.DateTime;
import org.jooq.Converter;

import java.sql.Timestamp;

public class DateTimeConverter implements Converter<Timestamp, DateTime> {

    @Override
    public DateTime from(Timestamp databaseObject) {
        return new DateTime(databaseObject.getTime());
    }

    @Override
    public Timestamp to(DateTime dt) {
        return new Timestamp(dt.getMillis());
    }

    @Override
    public Class<Timestamp> fromType() {
        return Timestamp.class;
    }

    @Override
    public Class<DateTime> toType() {
        return DateTime.class;
    }
}

Jooq Configuration:

<configuration>
  <jdbc>
    <url>jdbc:h2:file:build/database</url>
    <driver>org.h2.Driver</driver>
    <user>sa</user>
  </jdbc>
  <generator>
    <database>
      <name>org.jooq.util.h2.H2Database</name>
      <inputSchema>PUBLIC</inputSchema>
      <includes>.*</includes>
      <customTypes>
        <customType>
          <name>org.joda.time.DateTime</name>
          <converter>n.b.jooqJodaTime.DateTimeConverter</converter>
        </customType>
      </customTypes>
      <forcedtypes>
        <forcedType>
          <name>org.joda.time.DateTime</name>
          <expression>.*DATETIME.*</expression>
        </forcedType>
      </forcedtypes>
    </database>
    <generate>
      <pojos>true</pojos>
      <immutablePojos>true</immutablePojos>
      <jpaAnnotations>true</jpaAnnotations>
      <validationAnnotations>true</validationAnnotations>
      <deprecated>false</deprecated>
    </generate>
    <target>
      <packageName>n.b.c.generated.jooq</packageName>
      <directory>src/main/java/</directory>
    </target>
  </generator>
</configuration>

And here are the results:

/**
 * The column <code>PUBLIC.NONSENSE.TEST_DATETIME</code>. 
 */
public final org.jooq.TableField<n.b.c.generated.jooq.tables.records.NonsenseRecord,

java.sql.Timestamp> TEST_DATETIME = createField("TEST_DATETIME", org.jooq.impl.SQLDataType.TIMESTAMP, this);

I'd like this to look like this:

/**
 * The column <code>PUBLIC.NONSENSE.TEST_DATETIME</code>. 
 */
public final org.jooq.TableField<n.b.c.generated.jooq.tables.records.NonsenseRecord,

org.joda.time.DateTime> TEST_DATETIME = createField("TEST_DATETIME", org.jooq.impl.SQLDataType.TIMESTAMP, this);

like image 280
babbitt Avatar asked Nov 12 '22 18:11

babbitt


1 Answers

This is probably due to a typo in your XML. (For historic reasons) the element should be called <expressions/> not <expression/>:

  <complexType name="ForcedType">
    <all>
      <!-- The name of the type to be forced upon various artefacts -->
      <element name="name" type="string" minOccurs="1" maxOccurs="1" />

      <!--
        A Java regular expression matching columns, parameters, attributes, 
        etc to be forced to have this type
        -->
      <element name="expressions" type="string" minOccurs="1" maxOccurs="1" />
    </all>
  </complexType>

See also the XSD for details. I think it's worth creating synonyms for the two element names in jOOQ 3.3. This is now registered as #2837

Another typo

There's another typo with the <forcedtypes/> element, which should be <forcedTypes/> !

like image 95
Lukas Eder Avatar answered Nov 15 '22 04:11

Lukas Eder