Merge remote-tracking branch 'upstream/master'

# Conflicts:
#	ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java
#	ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java
This commit is contained in:
Noemi Praml
2022-06-09 08:37:38 +02:00
13 changed files with 140 additions and 28 deletions
@@ -12,6 +12,7 @@ import java.util.Optional;
* </p>
* <pre>{@code
*
* @Component
* public class CustomerFinder extends BeanFinder<Long,Customer> {
*
* @Inject
@@ -26,29 +27,37 @@ import java.util.Optional;
*
* @param <I> The ID type
* @param <T> The Bean type
*
* @see BeanRepository
*/
@NonNullApi
public abstract class BeanFinder<I,T> {
/**
* Migrate to using database rather than server.
*/
@Deprecated
protected final Database server;
protected final Database database;
protected final Class<T> type;
/**
* Create with the given bean type and Database instance.
*
* @param type The bean type
* @param server The Database instance typically created via Spring factory or equivalent.
* @param database The Database instance typically created via Spring factory or equivalent.
*/
protected BeanFinder(Class<T> type, Database server) {
protected BeanFinder(Class<T> type, Database database) {
this.type = type;
this.server = server;
this.database = database;
this.server = database;
}
/**
* Return the Database to use.
*/
public Database db() {
return server;
return database;
}
/**
@@ -70,10 +79,10 @@ public abstract class BeanFinder<I,T> {
* <p>
* This is equivalent to {@link DB#byName(String)}
*
* @param server The name of the Database. If this is null then the default Database is returned.
* @param name The name of the Database. If this is null then the default Database is returned.
*/
public Database db(String server) {
return DB.byName(server);
public Database db(String name) {
return DB.byName(name);
}
/**
@@ -6,11 +6,15 @@ import io.ebean.bean.EntityBean;
import java.util.Collection;
/**
* Provides finder functionality for use with "Dependency Injection style" use of Ebean.
* Provides find and persist functionality for use with "Dependency Injection style" use of Ebean.
* <p>
* Extend the BeanRepository with additional finder and persisting methods as needed by the
* application. The intention is to keep all the related logic together, for example, all the
* persisting and finding logic for Customer would be in CustomerRepository.
*
* <pre>{@code
*
* @Repository
* @Component
* public class CustomerRepository extends BeanRepository<Long,Customer> {
*
* @Inject
@@ -50,10 +54,10 @@ public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
* }</pre>
*
* @param type The bean type
* @param server The Database instance typically created via Spring factory or equivalent
* @param database The Database instance typically created via Spring factory or equivalent
*/
protected BeanRepository(Class<T> type, Database server) {
super(type, server);
protected BeanRepository(Class<T> type, Database database) {
super(type, database);
}
/**
@@ -122,8 +126,8 @@ public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
/**
* Save all the beans in the collection.
*/
public int saveAll(Collection<T> bean) {
return db().saveAll(bean);
public int saveAll(Collection<T> beans) {
return db().saveAll(beans);
}
/**
@@ -8,6 +8,9 @@ import java.util.List;
* Intended to be used as a base class for 'Finder' implementations that can then
* be injected or used as public static fields on the associated entity bean.
* <p>
* When using dependency injection {@link BeanRepository} and {@link BeanFinder}
* are expected to be used rather than this Finder.
* <p>
* These 'finders' are a place to organise all the finder methods for that bean type
* and specific finder methods are expected to be added (find by unique properties etc).
* </p>
@@ -54,6 +57,8 @@ import java.util.List;
*
* }</pre>
*
* @see BeanRepository
* @see BeanFinder
*/
@NonNullApi
public class Finder<I, T> {
@@ -13,11 +13,10 @@ public interface DataTimeZone {
Calendar getTimeZone();
/**
* Return the Calendar to use for Timezone information when reading/writing date.
* A 'date' only value has normally no timezone information, but some platforms (like MySQL)
* reqire this.
* Return the Calendar to use for Timezone information when reading/writing a time component (date only/time only).
* A time component has normally no timezone information, but some platforms (like MySQL) reqire this.
*/
default Calendar getDateTimeZone() {
default Calendar getTimeComponentTimeZone() {
return null;
}
}
@@ -19,7 +19,7 @@ public class MySqlDataTimeZone implements DataTimeZone {
}
@Override
public Calendar getDateTimeZone() {
public Calendar getTimeComponentTimeZone() {
return zone;
}
}
@@ -158,7 +158,7 @@ public class DataBind implements DataBinder {
@Override
public final void setDate(java.sql.Date v) throws SQLException {
Calendar timeZone = dataTimeZone.getDateTimeZone();
Calendar timeZone = dataTimeZone.getTimeComponentTimeZone();
if (timeZone != null) {
pstmt.setDate(++pos, v, timeZone);
} else {
@@ -178,7 +178,7 @@ public class DataBind implements DataBinder {
@Override
public final void setTime(Time v) throws SQLException {
Calendar timeZone = dataTimeZone.getDateTimeZone();
Calendar timeZone = dataTimeZone.getTimeComponentTimeZone();
if (timeZone != null) {
pstmt.setTime(++pos, v, timeZone);
} else {
@@ -107,7 +107,7 @@ public class RsetDataReader implements DataReader {
@Override
public final Date getDate() throws SQLException {
Calendar cal = dataTimeZone.getDateTimeZone();
Calendar cal = dataTimeZone.getTimeComponentTimeZone();
if (cal != null) {
return rset.getDate(pos(), cal);
} else {
@@ -156,7 +156,7 @@ public class RsetDataReader implements DataReader {
@Override
public final Time getTime() throws SQLException {
Calendar cal = dataTimeZone.getDateTimeZone();
Calendar cal = dataTimeZone.getTimeComponentTimeZone();
if (cal != null) {
return rset.getTime(pos(), cal);
} else {
+1 -1
View File
@@ -16,7 +16,7 @@
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.2.2</version>
<version>4.2.3</version>
</dependency>
<dependency>
@@ -6,8 +6,6 @@ import org.tests.model.basic.Customer;
import java.util.List;
//import javax.inject.Inject;
public class CustomerRepository extends BeanRepository<Integer, Customer> {
//@Inject
@@ -28,7 +26,6 @@ public class CustomerRepository extends BeanRepository<Integer, Customer> {
}
public int updateNotes(String blah, String whot) {
return updateQuery()
.set("smallnote", whot)
.where().eq("name", blah)
@@ -0,0 +1,69 @@
package org.tests.timezone;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.time.LocalTime;
import static org.assertj.core.api.Assertions.assertThat;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class LocalTimeTest {
protected String platform="h2";
protected Database db;
@BeforeAll
public void startTest() {
db = createServer("GMT"); // test uses GMT database
}
@AfterAll
public void shutdown() {
if (db != null) {
db.find(MLocalTime.class).delete();
db.shutdown();
}
}
/**
* The test checks the write and read of LocalTime values. The database is in GMT time zone.
* In order to verify the test in different java time zones (where the application runs),
* use the <code>-Duser.timezone</code> as JVM argument,
* e.g. <code>-Duser.timezone="America/New_York"</code> or <code>-Duser.timezone="PST"</code>>
* or any other timezone: <a href="https://garygregory.wordpress.com/2013/06/18/what-are-the-java-timezone-ids/">https://garygregory.wordpress.com/2013/06/18/what-are-the-java-timezone-ids/</a>.
*/
@Test
public void testLocalTime() {
LocalTime lt = LocalTime.of(5, 15, 15);
assertThat(db.find(MLocalTime.class).findCount()).isEqualTo(0);
db.sqlUpdate("insert into mlocal_time (id, local_time) values (1, '05:15:15')").execute();
int count = db.find(MLocalTime.class).where().eq("local_time", lt).findCount();
assertThat(count).isEqualTo(1);
MLocalTime dbModel = db.find(MLocalTime.class).where().eq("local_time", lt).findOne();
assertThat(dbModel.getLocalTime().toString()).isEqualTo(lt.toString());
}
private Database createServer(String dbTimeZone) {
DatabaseConfig config = new DatabaseConfig();
config.setName(platform);
config.loadFromProperties();
config.setDdlExtra(false);
config.setDefaultServer(false);
config.setRegister(false);
config.setChangeLogAsync(false);
config.addClass(MLocalTime.class);
config.setDumpMetricsOnShutdown(false);
config.setDataTimeZone(dbTimeZone);
return DatabaseFactory.create(config);
}
}
@@ -0,0 +1,28 @@
package org.tests.timezone;
import javax.annotation.Nullable;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.time.LocalTime;
@Entity
public class MLocalTime {
@Id
private Integer id;
@Nullable
private LocalTime localTime;
@Nullable
public LocalTime getLocalTime() {
return localTime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
@@ -0,0 +1 @@
io.ebean.querybean.generator.Processor,aggregating
@@ -1 +1 @@
io.ebean.querybean.generator.Processor,isolating
io.ebean.querybean.generator.Processor,aggregating