forked from ebean-orm-examples/example-minimal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
init minimal-test-project to reproduce issue-2919: ebean-orm/ebean#2919
- Loading branch information
chuanliang
committed
Feb 14, 2023
1 parent
11c1788
commit 7bca8e5
Showing
4 changed files
with
356 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/main/java/org/example/domain/LeadsWebActionDataCountAggregate1.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package org.example.domain; | ||
|
||
import java.util.Date; | ||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
|
||
|
||
/** | ||
* for example | ||
*/ | ||
@Entity | ||
public class LeadsWebActionDataCountAggregate1 { | ||
|
||
@Column(name = "effective_action_type") | ||
private String effectiveActionType; | ||
|
||
@Column(name = "effective_action_time") | ||
private Date effectiveActionTime; | ||
|
||
/** | ||
* this field must comply with this standard: if the sql's column is action_count, its conventional camel | ||
* spelling is actionCount, if we use | ||
* <code> | ||
* @Column(name = "action_count") | ||
* private Integer count; | ||
* </code> | ||
* the column mapping will not work, and we will see empty result record: effectiveActionType and | ||
* effectiveActionTime will also be null. | ||
*/ | ||
@Column(name = "action_count") | ||
private Integer actionCount; | ||
|
||
/** | ||
* get the value of effectiveActionType | ||
* | ||
* @return the value of effectiveActionType | ||
*/ | ||
public String getEffectiveActionType() { | ||
return effectiveActionType; | ||
} | ||
|
||
/** | ||
* set the value of the effectiveActionType | ||
* | ||
* @param effectiveActionType the value of effectiveActionType | ||
*/ | ||
public void setEffectiveActionType(String effectiveActionType) { | ||
this.effectiveActionType = effectiveActionType; | ||
} | ||
|
||
/** | ||
* get the value of effectiveActionTime | ||
* | ||
* @return the value of effectiveActionTime | ||
*/ | ||
public Date getEffectiveActionTime() { | ||
return effectiveActionTime; | ||
} | ||
|
||
/** | ||
* set the value of the effectiveActionTime | ||
* | ||
* @param effectiveActionTime the value of effectiveActionTime | ||
*/ | ||
public void setEffectiveActionTime(Date effectiveActionTime) { | ||
this.effectiveActionTime = effectiveActionTime; | ||
} | ||
|
||
/** | ||
* get the value of actionCount | ||
* | ||
* @return the value of actionCount | ||
*/ | ||
public Integer getActionCount() { | ||
return actionCount; | ||
} | ||
|
||
/** | ||
* set the value of the actionCount | ||
* | ||
* @param actionCount the value of actionCount | ||
*/ | ||
public void setActionCount(Integer actionCount) { | ||
this.actionCount = actionCount; | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
src/main/java/org/example/domain/LeadsWebActionDataCountAggregate2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package org.example.domain; | ||
|
||
import java.util.Date; | ||
import javax.persistence.Column; | ||
|
||
|
||
/** | ||
* for example | ||
*/ | ||
public class LeadsWebActionDataCountAggregate2 { | ||
|
||
@Column(name = "effective_action_time") | ||
private Date effectiveActionTime; | ||
|
||
|
||
@Column(name = "effective_action_type") | ||
private String effectiveActionType; | ||
|
||
@Column(name = "action_count") | ||
private Integer actionCount; | ||
|
||
/** | ||
* get the value of effectiveActionTime | ||
* | ||
* @return the value of effectiveActionTime | ||
*/ | ||
public Date getEffectiveActionTime() { | ||
return effectiveActionTime; | ||
} | ||
|
||
/** | ||
* set the value of the effectiveActionTime | ||
* | ||
* @param effectiveActionTime the value of effectiveActionTime | ||
*/ | ||
public void setEffectiveActionTime(Date effectiveActionTime) { | ||
this.effectiveActionTime = effectiveActionTime; | ||
} | ||
|
||
/** | ||
* get the value of effectiveActionType | ||
* | ||
* @return the value of effectiveActionType | ||
*/ | ||
public String getEffectiveActionType() { | ||
return effectiveActionType; | ||
} | ||
|
||
/** | ||
* set the value of the effectiveActionType | ||
* | ||
* @param effectiveActionType the value of effectiveActionType | ||
*/ | ||
public void setEffectiveActionType(String effectiveActionType) { | ||
this.effectiveActionType = effectiveActionType; | ||
} | ||
|
||
/** | ||
* get the value of actionCount | ||
* | ||
* @return the value of actionCount | ||
*/ | ||
public Integer getActionCount() { | ||
return actionCount; | ||
} | ||
|
||
/** | ||
* set the value of the actionCount | ||
* | ||
* @param actionCount the value of actionCount | ||
*/ | ||
public void setActionCount(Integer actionCount) { | ||
this.actionCount = actionCount; | ||
} | ||
} |
179 changes: 179 additions & 0 deletions
179
src/main/java/org/example/domain/LeadsWebActionDataDao.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
package org.example.domain; | ||
|
||
|
||
import com.zaxxer.hikari.HikariConfig; | ||
import com.zaxxer.hikari.HikariDataSource; | ||
import io.ebean.EbeanServer; | ||
import io.ebean.EbeanServerFactory; | ||
import io.ebean.Query; | ||
import io.ebean.config.ServerConfig; | ||
import java.util.List; | ||
|
||
/** | ||
* | ||
* @author magicliang | ||
* | ||
*/ | ||
|
||
public class LeadsWebActionDataDao { | ||
private static final String RAW_SQL = "select\n" | ||
+ " effective_action_type,\n" | ||
+ " CAST(min_action_time2 AS DATE) as effective_action_time,\n" | ||
+ " count(*) as action_count\n\n" | ||
+ " from\n" | ||
+ " (\n" | ||
+ " select\n" | ||
+ " effective_action_type,\n" | ||
+ " sign_id,\n" | ||
+ " min(action_time2) as min_action_time2\n" | ||
+ " from\n" | ||
+ " (\n" | ||
+ " select\n" | ||
+ " sign_id,\n" | ||
+ " action_time2,\n" | ||
+ " CASE\n" | ||
+ " WHEN final_action_type = 'wx_1166' THEN '405'\n" | ||
+ " ELSE final_action_type\n" | ||
+ " END AS effective_action_type\n" | ||
+ " from\n" | ||
+ " leads_web_action_data\n" | ||
+ " where\n" | ||
+ " action_time2 between :actionTimeEnd\n" | ||
+ " and :actionTimeEnd\n" | ||
+ " and all_id = :all_id\n" | ||
+ " AND (\n" | ||
+ " OR og in (\n" | ||
+ " 6,\n" | ||
+ " 104,\n" | ||
+ " 105,\n" | ||
+ " 427,\n" | ||
+ " 204,\n" | ||
+ " 108,\n" | ||
+ " 302,\n" | ||
+ " 10000,\n" | ||
+ " 402,\n" | ||
+ " 403,\n" | ||
+ " 405,\n" | ||
+ " 502,\n" | ||
+ " 504,\n" | ||
+ " 409,\n" | ||
+ " 316,\n" | ||
+ " 412\n" | ||
+ " )\n" | ||
+ " OR og is null\n" | ||
+ " )\n" | ||
+ " order by\n" | ||
+ " action_time2 desc\n" | ||
+ " )\n" | ||
+ " group by\n" | ||
+ " effective_action_type,\n" | ||
+ " sign_id\n" | ||
+ " )\n" | ||
+ " group by\n" | ||
+ " effective_action_type,\n" | ||
+ " CAST(min_action_time2 AS DATE)\n" | ||
+ " </code>"; | ||
|
||
|
||
/** | ||
* issue 1: | ||
* | ||
* this query will return [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{} | ||
* ,{},{},{},{},{},{},{}] | ||
* condition to reproduce the empty records: | ||
* | ||
* for column action_count, we can use actionCount as member field, but if we want another name for business | ||
* purpose for examle "count", instead of actionCount as conventional name: | ||
* <code> | ||
* @Column(name = "action_count") | ||
* private Integer count; | ||
* </code> | ||
* | ||
* the column mapping will not work, and the whole result will be empty, that means column mapping annotation is | ||
* useless. | ||
* | ||
* @return list with empty records | ||
*/ | ||
public List<LeadsWebActionDataCountAggregate1> findNative() { | ||
Query<LeadsWebActionDataCountAggregate1> basicQuery = | ||
getServer().findNative(LeadsWebActionDataCountAggregate1.class, | ||
RAW_SQL) | ||
.setParameter("all_id", 12345) | ||
.setParameter("actionTimeBegin", "2022-11-11 00:00:00") | ||
.setParameter("actionTimeEnd", "2022-11-11 23:59:59"); | ||
return basicQuery.findList(); | ||
} | ||
|
||
/** | ||
* issue2: | ||
* as we can see the raw sql, the result of SQL is: | ||
* | ||
* effective_action_type, effective_action_time, action_count | ||
* | ||
* They can be mapped to java type: String, Date, Integer | ||
* | ||
* If we declare our instance member like this(the order is Integer): | ||
* <code> | ||
* | ||
* @return an exception will be thrown, there will be no result | ||
* @Column(name = "effective_action_time") | ||
* * private Date effectiveActionTime; | ||
* @Column(name = "effective_action_type") | ||
* * private String effectiveActionType; | ||
* @Column(name = "action_count") | ||
* private Integer actionCount; | ||
* </code> | ||
* | ||
* We declare effectiveActionTime before effectiveActionType, we want the ebean to map column result of | ||
* effective_action_time to effectiveActionTime, and we get an exception here: | ||
* | ||
* javax.persistence.PersistenceException: Query threw SQLException:Text '204' could not be parsed at index | ||
* 0 | ||
* Query was: select | ||
* | ||
* the 204 is result for column effective_action_type, as the first column result. ebean tries to map it | ||
* to first instance member because it is first column in result set, ignoring that the mapped variable | ||
* for effective_action_type accoriding to mapping is the second member variable. | ||
* | ||
* So the ebean actual behavior is, when we use findDto api, the sequence of member is important, the | ||
* mapping annotation is useless. | ||
*/ | ||
public List<LeadsWebActionDataCountAggregate2> findDto() { | ||
return getServer().findDto(LeadsWebActionDataCountAggregate2.class, RAW_SQL) | ||
.setParameter("all_id", 12345) | ||
.setParameter("actionTimeBegin", "2022-11-11 00:00:00") | ||
.setParameter("actionTimeEnd", "2022-11-11 23:59:59") | ||
.findList(); | ||
} | ||
|
||
static public synchronized EbeanServer getServer() { | ||
HikariConfig config = new HikariConfig(); | ||
config.setDriverClassName("com.clickhouse.jdbc.ClickHouseDriver"); | ||
config.setJdbcUrl("jdbc:clickhouse://localhost:8123/myclickhouse-db"); | ||
config.setUsername("myclickhouse.username"); | ||
config.setPassword("myclickhouse.passwd"); | ||
config.setConnectionTimeout(30000L); | ||
config.setMinimumIdle(5); | ||
config.setIdleTimeout(30000L); | ||
config.setMaximumPoolSize(50); | ||
config.setMaxLifetime(180000L); | ||
config.setValidationTimeout(5000L); | ||
config.setConnectionTestQuery("select 1"); | ||
config.setRegisterMbeans(true); | ||
config.setConnectionInitSql(null); | ||
config.addDataSourceProperty("cachePrepStmts", "true"); | ||
config.addDataSourceProperty("prepStmtCacheSize", "250"); | ||
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); | ||
|
||
|
||
ServerConfig serverConfig = new ServerConfig(); | ||
serverConfig.setName("clickhouseserver"); | ||
serverConfig.setDataSource(new HikariDataSource(config)); | ||
serverConfig.setRegister(true); | ||
serverConfig.setDefaultServer(false); | ||
serverConfig.addPackage("leads.models"); | ||
EbeanServer ebeanServer = EbeanServerFactory.create(serverConfig); | ||
return ebeanServer; | ||
} | ||
} |