Skip to content

Instantly share code, notes, and snippets.

@hastebrot
Created September 5, 2012 09:46
Show Gist options
  • Save hastebrot/3634242 to your computer and use it in GitHub Desktop.
Save hastebrot/3634242 to your computer and use it in GitHub Desktop.
package sscce;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.Query;
import com.avaje.ebean.QueryIterator;
import com.avaje.ebean.config.AutofetchConfig;
import com.avaje.ebean.config.DataSourceConfig;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebeaninternal.server.core.DefaultServer;
import com.avaje.ebeaninternal.server.ddl.DdlGenerator;
/**
* <h1>Simple Database Service with Ebean ORM</h1>
*
* <p>This Short, Self Contained, Correct Example (SSCCE) shows three pitfalls I
* stumpled upon.
*
* <p><b>Required Libraries:</b> ebean-2.7.4.jar, h2-1.3.164.jar, persistence-api-1.0.jar,
* servlet-api-2.5.jar.
*
* <h2>Pitfall #1: Used special characters in the name of ServerConfig</h2>
*
* <pre>
* WRONG:
* this.serverConfig.setName("h2:mem:ebean");
* this.serverConfig.setName("h2.mem.ebean");
*
* RIGHT:
* this.serverConfig.setName(this.sluggifyText("h2:mem:ebean"));
* </pre>
*
* <h2>Pitfall #2: Forgot to implement getters and setters in the entity bean</h2>
*
* <pre>
* WRONG:
* france.capitalName = "Paris";
* System.out.println(france.capitalName);
* this.ebeanServer.insert(france);
*
* RIGHT:
* france.setCapitalName("Paris");
* System.out.println(france.getCapitalName());
* this.ebeanServer.insert(france);
* </pre>
*
* <h2>Pitfall #3. Connection in QueryIterator wasn't closed</h2>
*
* <pre>
* WRONG:
* QueryIterator<Country> queryIterator = query.findIterate();
*
* RIGHT:
* QueryIterator<Country> queryIterator = query.findIterate();
* queryIterator.close();
* </pre>
*/
public class SimpleEbeanService {
//-----------------------------------------------------------------------------------
// MAIN METHOD.
//-----------------------------------------------------------------------------------
public static void main(String[] args) {
SimpleEbeanService service = new SimpleEbeanService();
System.out.println("Initializing database...");
service.addEntityClass(Country.class);
service.initDataSourceConfig();
service.initAutofetchConfig();
service.initServerConfig();
System.out.println("Connecting to database...");
service.initEbeanServer();
System.out.println("Running queries...");
service.runCreateTableQueries();
service.runInsertDatasetQuery();
service.runSelectDatasetQueries();
}
//-----------------------------------------------------------------------------------
// PUBLIC FIELDS.
//-----------------------------------------------------------------------------------
public int maxConnections = 5;
public int numberOfQueries = 20;
public List<Class<?>> entityClasses = new ArrayList<Class<?>>();
public DataSourceConfig dataSourceConfig;
public AutofetchConfig autofetchConfig;
public ServerConfig serverConfig;
public EbeanServer ebeanServer;
//-----------------------------------------------------------------------------------
// PUBLIC METHODS.
//-----------------------------------------------------------------------------------
public void addEntityClass(Class<?> entityClass) {
this.entityClasses.add(entityClass);
}
public void initDataSourceConfig() {
this.dataSourceConfig = new DataSourceConfig();
this.dataSourceConfig.setDriver("org.h2.Driver");
this.dataSourceConfig.setUrl("jdbc:h2:mem:ebean");
this.dataSourceConfig.setUsername("sa");
this.dataSourceConfig.setPassword("");
this.dataSourceConfig.setMaxConnections(this.maxConnections);
}
public void initAutofetchConfig() {
this.autofetchConfig = new AutofetchConfig();
this.autofetchConfig.setUseFileLogging(false);
this.autofetchConfig.setLogDirectory(".");
}
public void initServerConfig() {
this.serverConfig = new ServerConfig();
this.serverConfig.setLoggingToJavaLogger(true);
this.serverConfig.setLoggingDirectory(".");
this.serverConfig.setDataSourceConfig(this.dataSourceConfig);
this.serverConfig.setAutofetchConfig(this.autofetchConfig);
// PITFALL #1:
// javax.management.MalformedObjectNameException: Invalid character ':' in
// value part of property
//this.serverConfig.setName("h2:mem:ebean");
// PITFALL #1:
// java.lang.ClassFormatError: Illegal class name "sscce/SimpleEbeanService
// $Country$$EntityBean$h2.mem.ebean" in class file sscce/SimpleEbeanService
// $Country$$EntityBean$h2/mem/ebean
//this.serverConfig.setName("h2.mem.ebean");
this.serverConfig.setName(this.sluggifyText("h2:mem:ebean"));
this.serverConfig.setRegister(false);
this.serverConfig.setDefaultServer(false);
this.serverConfig.setClasses(this.entityClasses);
this.serverConfig.setDdlGenerate(false);
this.serverConfig.setDdlRun(false);
}
public void initEbeanServer() {
this.ebeanServer = EbeanServerFactory.create(this.serverConfig);
}
public void runCreateTableQueries() {
DdlGenerator generator = ((DefaultServer) this.ebeanServer).getDdlGenerator();
generator.runScript(true, generator.generateDropDdl());
generator.runScript(false, generator.generateCreateDdl());
}
public void runInsertDatasetQuery() {
Country france = new Country();
france.setName("France");
france.setCapitalName("Paris");
// PITFALL #2:
// Exception in thread "main" java.lang.RuntimeException: get id on [sscce.
// SimpleEbeanService$Country] type[sscce.SimpleEbeanService$Country] threw error.
this.ebeanServer.insert(france);
}
public void runSelectDatasetQueries() {
for (int index = 0; index < this.numberOfQueries; index += 1) {
Query<Country> query = this.ebeanServer.createQuery(Country.class)
.select("name, capitalName").where().eq("name", "France").query();
QueryIterator<Country> queryIterator = query.findIterate();
try {
while (queryIterator.hasNext()) {
Country country = queryIterator.next();
System.out.println(country);
}
}
finally {
// PITFALL #3:
// Exception in thread "main" javax.persistence.PersistenceException:
// java.sql.SQLException: Unsuccessfully waited [1000] millis for a
// connection to be returned. No connections are free. You need to
// Increase the max connections of [5] or look for a connection pool
// leak using datasource.xxx.capturestacktrace=true
queryIterator.close();
}
}
}
//-----------------------------------------------------------------------------------
// PRIVATE METHODS.
//-----------------------------------------------------------------------------------
private String sluggifyText(String text) {
text = text.toLowerCase();
text = text.replaceAll("[^a-z0-9]+", "_");
text = text.replaceAll("_$|^_", "");
return text;
}
//-----------------------------------------------------------------------------------
// PUBLIC CLASSES.
//-----------------------------------------------------------------------------------
@Entity
public static class Country {
private @Id Integer id;
private String name;
private String capitalName;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCapitalName() { return capitalName; }
public void setCapitalName(String capitalName) { this.capitalName = capitalName; }
public String toString() {
return "<Country name='" + this.name + "' " +
"capitalName='" + this.capitalName + "'>";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment