Skip to content
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

Add database columns with CURRENT_TIMESTAMP support #30

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Maven plugin to run the code generator is also available.
```xml
<plugin>
<groupId>com.smartnews</groupId>
<artifactId>maven-jpa-entity-generator-plugin</artifactId>
<artifactId>jpa-entity-generator-maven-plugin</artifactId>
<version>0.99.8</version>
<dependencies>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.smartnews</groupId>
<artifactId>maven-jpa-entity-generator-plugin</artifactId>
<artifactId>jpa-entity-generator-maven-plugin</artifactId>
slankka marked this conversation as resolved.
Show resolved Hide resolved
<packaging>maven-plugin</packaging>
<version>0.99.8</version>
<name>maven-entitygen-plugin Maven Mojo</name>
Expand Down
9 changes: 9 additions & 0 deletions sample/src/main/java/com/example/entity/BlogArticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public class BlogArticle implements Serializable {
@Nonnull
@Column(name = "\"created_at\"", nullable = false)
private Timestamp createdAt;
@Nullable
@Column(name = "\"state\"", nullable = true)
private Byte state;
@Nullable
@Column(name = "\"create_time\"", nullable = true, insertable = false, updatable = false)
private Timestamp createTime;
@Nullable
@Column(name = "\"update_time\"", nullable = true, insertable = false, updatable = false)
private Timestamp updateTime;

@lombok.Setter(lombok.AccessLevel.NONE)
@ManyToOne
Expand Down
9 changes: 9 additions & 0 deletions sample/src/main/java/com/example/entity/jpa1/BlogArticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public class BlogArticle implements Serializable {
@Nonnull
@Column(name = "`created_at`", nullable = false)
private Timestamp createdAt;
@Nullable
@Column(name = "`state`", nullable = true)
private Byte state;
@Nullable
@Column(name = "`create_time`", nullable = true, insertable = false, updatable = false)
private Timestamp createTime;
@Nullable
@Column(name = "`update_time`", nullable = true, insertable = false, updatable = false)
private Timestamp updateTime;

@lombok.Setter(lombok.AccessLevel.NONE)
@ManyToOne
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -100,7 +101,13 @@ public static void generateAll(CodeGeneratorConfig originalConfig, boolean isJpa
f.setName(fieldName);
f.setColumnName(c.getName());
f.setNullable(c.isNullable());

if ((c.getTypeName().equalsIgnoreCase("DATETIME")
|| c.getTypeName().equalsIgnoreCase("TIMESTAMP"))
&& StringUtils.contains(c.getColumnDef(), "CURRENT_TIMESTAMP")
) {
f.setInsertable(false);
f.setUpdatable(false);
}
f.setComment(buildFieldComment(className, f.getName(), c, config.getFieldAdditionalCommentRules()));

f.setAnnotations(config.getFieldAnnotationRules().stream()
Expand Down Expand Up @@ -206,7 +213,7 @@ public static void generateAll(CodeGeneratorConfig originalConfig, boolean isJpa
if (!Files.exists(path)) {
Files.createFile(path);
}
Files.write(path, code.getBytes());
Files.write(path, code.getBytes(StandardCharsets.UTF_8));
slankka marked this conversation as resolved.
Show resolved Hide resolved

log.debug("path: {}, code: {}", path, code);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public static class Field {
private boolean primaryKey;
private boolean autoIncrement;
private boolean primitive;
private boolean insertable = true;
private boolean updatable = true;
private String generatedValueStrategy;
private List<Annotation> annotations = new ArrayList<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class Column {
private String name;
private int typeCode;
private String typeName;
private String columnDef;
private boolean nullable;
private boolean primaryKey;
private boolean autoIncrement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public List<String> getTableNames(JDBCSettings jdbcSettings) throws SQLException
DatabaseMetaData databaseMeta = getMetadata(jdbcSettings);
try {
List<String> tableNames = new ArrayList<>();
try (ResultSet rs = databaseMeta.getTables(null, jdbcSettings.getSchemaPattern(), "%", TABLE_TYPES)) {
try (ResultSet rs = databaseMeta.getTables(databaseMeta.getConnection().getCatalog(), jdbcSettings.getSchemaPattern(), "%", TABLE_TYPES)) {
while (rs.next()) {
tableNames.add(rs.getString("TABLE_NAME"));
}
Expand All @@ -52,7 +52,8 @@ public Table getTable(JDBCSettings jdbcSettings, String schemaAndTable) throws S
tableInfo.setSchema(Optional.ofNullable(schema));
DatabaseMetaData databaseMeta = getMetadata(jdbcSettings);
try {
try (ResultSet rs = databaseMeta.getTables(null, schema, table, TABLE_TYPES)) {
String catalog = databaseMeta.getConnection().getCatalog();
try (ResultSet rs = databaseMeta.getTables(catalog, schema, table, TABLE_TYPES)) {
if (rs.next()) {
tableInfo.setDescription(Optional.ofNullable(rs.getString("REMARKS")));
}
Expand All @@ -61,18 +62,18 @@ public Table getTable(JDBCSettings jdbcSettings, String schemaAndTable) throws S
}

final List<String> primaryKeyNames = new ArrayList<>();
try (ResultSet rs = databaseMeta.getPrimaryKeys(null, schema, table)) {
try (ResultSet rs = databaseMeta.getPrimaryKeys(catalog, schema, table)) {
while (rs.next()) {
primaryKeyNames.add(rs.getString("COLUMN_NAME"));
}
}
try (ResultSet rs = databaseMeta.getColumns(null, schema, table, "%")) {
try (ResultSet rs = databaseMeta.getColumns(catalog, schema, table, "%")) {
while (rs.next()) {
Column column = new Column();
column.setName(rs.getString("COLUMN_NAME"));
column.setTypeCode(rs.getInt("DATA_TYPE"));
column.setTypeName(rs.getString("TYPE_NAME"));

column.setColumnDef(rs.getString("COLUMN_DEF"));
// Oracle throws java.sql.SQLException: Invalid column name
boolean autoIncrement = false;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public static String toJavaType(int typeCode) {
return "Long";
// case Types.BINARY:
case Types.BIT:
// return "Boolean";
return "boolean";
// my sql
slankka marked this conversation as resolved.
Show resolved Hide resolved
return "Boolean";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be a breaking change. If I remember correctly, setting primitive type here means the value will be false if absent. Is there any reason you changed this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the database has a nullable column, primitive type field of the entity can't store null, NPE will occur. Wrapped Type can represent true/false and not set

Copy link
Author

@slankka slankka Nov 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we force make all boolean fields to be not null.
There is an another situation:

Sometimes, we use ExampleMatcher of JPA, and telling JPA to ignore the null value field:

ExampleMatcher.matchingAll().withIgnoreNullValues()

or mybatis :

<if test="aNullableBooleanState != null">
a_nullable_boolean_state= #{aNullableBooleanState, jdbcType="BIT"}
</if>

If the field type is primitive, we will always query data with and field =true/false, can't leave this query without this condition.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slankka
I'm terribly sorry for my belated response here.

That makes sense. That said, I'd like to avoid bringing any breaking changes to this library. This library is widely used at SmartNews and I am no longer working for the company.

If you're still interested in working this PR and have time for it, could you introduce a flag in the configuration allowing users to choose Boolean over the primitive type plus set it as false by default?

case Types.BLOB:
return "Blob";
case Types.BOOLEAN:
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/entityGen/entity.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ ${field.comment}
<#if requireJSR305 && !field.primitive>
<#if field.nullable>@Nullable<#else>@Nonnull</#if>
</#if>
@Column(name = "<#if jpa1Compatible>`<#else>\"</#if>${field.columnName}<#if jpa1Compatible>`<#else>\"</#if>", nullable = ${field.nullable?c})
@Column(name = "<#if jpa1Compatible>`<#else>\"</#if>${field.columnName}<#if jpa1Compatible>`<#else>\"</#if>", nullable = ${field.nullable?c}<#if !field.insertable>, insertable = false</#if><#if !field.updatable>, updatable = false</#if>)
private ${field.type} ${field.name}<#if field.defaultValue??> = ${field.defaultValue}</#if>;
</#list>
<#list bottomAdditionalCodeList as code>
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/com/example/entity/BlogArticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public class BlogArticle implements Serializable {
private Clob tags;
@Column(name = "\"created_at\"", nullable = false)
private Timestamp createdAt;
@Column(name = "\"state\"", nullable = true)
private Byte state;
@Column(name = "\"create_time\"", nullable = true, insertable = false, updatable = false)
private Timestamp createTime;
@Column(name = "\"update_time\"", nullable = true, insertable = false, updatable = false)
private Timestamp updateTime;

@lombok.Setter(lombok.AccessLevel.NONE)
@ManyToOne
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/com/example/entity/jpa1/BlogArticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public class BlogArticle implements Serializable {
private Clob tags;
@Column(name = "`created_at`", nullable = false)
private Timestamp createdAt;
@Column(name = "`state`", nullable = true)
private Byte state;
@Column(name = "`create_time`", nullable = true, insertable = false, updatable = false)
private Timestamp createTime;
@Column(name = "`update_time`", nullable = true, insertable = false, updatable = false)
private Timestamp updateTime;

@lombok.Setter(lombok.AccessLevel.NONE)
@ManyToOne
Expand Down
9 changes: 9 additions & 0 deletions src/test/java/com/example/entity2/BlogArticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,13 @@ public class BlogArticle implements Serializable {
@Nonnull
@Column(name = "\"created_at\"", nullable = false)
private Timestamp createdAt;
@Nullable
@Column(name = "\"state\"", nullable = true)
private Byte state;
@Nullable
@Column(name = "\"create_time\"", nullable = true, insertable = false, updatable = false)
private Timestamp createTime;
@Nullable
@Column(name = "\"update_time\"", nullable = true, insertable = false, updatable = false)
private Timestamp updateTime;
}
9 changes: 9 additions & 0 deletions src/test/java/com/example/entity2/jpa1/BlogArticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,13 @@ public class BlogArticle implements Serializable {
@Nonnull
@Column(name = "`created_at`", nullable = false)
private Timestamp createdAt;
@Nullable
@Column(name = "`state`", nullable = true)
private Byte state;
@Nullable
@Column(name = "`create_time`", nullable = true, insertable = false, updatable = false)
private Timestamp createTime;
@Nullable
@Column(name = "`update_time`", nullable = true, insertable = false, updatable = false)
private Timestamp updateTime;
}
5 changes: 4 additions & 1 deletion src/test/java/com/example/unit/DatabaseUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public static void init() throws SQLException, ClassNotFoundException {
"id integer primary key auto_increment not null, " +
"blog_id integer comment 'database comment for blog_id' references blog(id), " +
"name varchar(30), tags text, " +
"created_at timestamp not null" +
"created_at timestamp not null, " +
"state TINYINT(1), " +
"create_time datetime DEFAULT CURRENT_TIMESTAMP, " +
"update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" +
")").execute();
conn.prepareStatement("create table tag (" +
"id integer primary key auto_increment not null, " +
Expand Down