Skip to content

Commit 6d31960

Browse files
committed
Add Issue21Test to reproduce the Problem in Issue #21. Adding a Note in the README.
1 parent ace6d7c commit 6d31960

3 files changed

Lines changed: 119 additions & 1 deletion

File tree

JSqlServerBulkInsert/src/main/java/de/bytefish/jsqlserverbulkinsert/SqlServerBulkInsert.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public class SqlServerBulkInsert<TEntity> implements ISqlServerBulkInsert<TEntit
2121

2222
private final AbstractMapping<TEntity> mapping;
2323

24-
2524
public SqlServerBulkInsert(AbstractMapping<TEntity> mapping)
2625
{
2726
this.mapping = mapping;
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package de.bytefish.jsqlserverbulkinsert.test.issues;
2+
3+
import de.bytefish.jsqlserverbulkinsert.SqlServerBulkInsert;
4+
import de.bytefish.jsqlserverbulkinsert.mapping.AbstractMapping;
5+
import de.bytefish.jsqlserverbulkinsert.model.SchemaMetaData;
6+
import de.bytefish.jsqlserverbulkinsert.test.base.TransactionalTestBase;
7+
import de.bytefish.jsqlserverbulkinsert.test.mapping.UTCNanoTest;
8+
import de.bytefish.jsqlserverbulkinsert.test.model.Person;
9+
import de.bytefish.jsqlserverbulkinsert.test.utils.MeasurementUtils;
10+
import de.bytefish.jsqlserverbulkinsert.util.SchemaUtils;
11+
import org.junit.Assert;
12+
import org.junit.Test;
13+
14+
import java.sql.*;
15+
import java.time.Clock;
16+
import java.time.LocalDate;
17+
import java.time.LocalDateTime;
18+
import java.time.ZoneOffset;
19+
import java.time.temporal.ChronoUnit;
20+
import java.time.temporal.TemporalUnit;
21+
import java.util.*;
22+
23+
/**
24+
* https://github.com/JSqlServerBulkInsert/JSqlServerBulkInsert/issues/17
25+
*/
26+
public class Issue21Test extends TransactionalTestBase {
27+
28+
public class Issue21Entity {
29+
30+
public LocalDateTime lastUpdate;
31+
32+
public Issue21Entity(LocalDateTime lastUpdate) {
33+
this.lastUpdate = lastUpdate;
34+
}
35+
36+
public LocalDateTime getLastUpdate() {
37+
return lastUpdate;
38+
}
39+
}
40+
41+
public class Issue21EntityMapping extends AbstractMapping<Issue21Entity> {
42+
43+
public Issue21EntityMapping() {
44+
super("dbo", "UnitTest");
45+
46+
mapLocalDateTime("LastUpdated", x -> x.getLastUpdate().truncatedTo(ChronoUnit.MILLIS));
47+
}
48+
}
49+
50+
@Override
51+
protected void onSetUpInTransaction() throws Exception {
52+
createTestTable();
53+
}
54+
55+
@Test
56+
public void bulkInsertToDateTimeColumn() throws SQLException {
57+
58+
// Expected LocalDate 2017-05-15T12:09:07.161013600
59+
LocalDateTime current = LocalDateTime.now(Clock.systemUTC());
60+
61+
// Create entities
62+
List<Issue21Entity> entities = Arrays.asList(new Issue21Entity (current));
63+
// Create the BulkInserter:
64+
Issue21EntityMapping mapping = new Issue21EntityMapping();
65+
// Now save all entities of a given stream:
66+
new SqlServerBulkInsert<>(mapping).saveAll(connection, entities.stream());
67+
68+
// And assert all have been written to the database:
69+
ResultSet rs = getAll();
70+
while (rs.next()) {
71+
// for debugging purposes, can look at how the dates are stored in the DB
72+
String dbDate = rs.getString("lastUpdated");
73+
// Get the Date we have written:
74+
LocalDateTime date = rs.getObject("lastUpdated", LocalDateTime.class);
75+
76+
// We should have a date:
77+
Assert.assertNotNull(date);
78+
79+
Assert.assertEquals(current.truncatedTo(ChronoUnit.SECONDS), date.truncatedTo(ChronoUnit.SECONDS));
80+
}
81+
}
82+
83+
private ResultSet getAll() throws SQLException {
84+
85+
String sqlStatement = "SELECT * FROM dbo.UnitTest";
86+
87+
Statement statement = connection.createStatement();
88+
89+
return statement.executeQuery(sqlStatement);
90+
}
91+
92+
private void createTestTable() throws SQLException {
93+
String sqlStatement = "CREATE TABLE [dbo].[UnitTest]\n" +
94+
" (\n" +
95+
" lastUpdated datetime" +
96+
" );";
97+
98+
Statement statement = connection.createStatement();
99+
100+
statement.execute(sqlStatement);
101+
}
102+
}

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,23 @@ private class MySampleEntityMapping extends AbstractMapping<MySampleEntity> {
111111
}
112112
```
113113

114+
### Notes on DATETIME Columns ###
115+
116+
If you are trying to map a `LocalDateTime` to a `DATETIME` column, you need to drop the nanoseconds part. A SQL Server `DATETIME` column doesn't have this level of precision.
117+
118+
It can be fixed by using `LocalDateTime#truncatedTo(ChronoUnit.MILLIS`, like this:
119+
120+
```java
121+
public class Issue21EntityMapping extends AbstractMapping<Issue21Entity> {
122+
123+
public Issue21EntityMapping() {
124+
super("dbo", "UnitTest");
125+
126+
mapLocalDateTime("LastUpdated", x -> x.getLastUpdate().truncatedTo(ChronoUnit.MILLIS));
127+
}
128+
}
129+
```
130+
114131
### Order of Columns ###
115132

116133
The ``SqlServerBulkCopy`` implementation of the Microsoft JDBC driver requires, that the destination schema and

0 commit comments

Comments
 (0)