safe query objects: statically typed objects as remotely executable queries by: william cook &...

22
Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Post on 20-Dec-2015

239 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Safe Query Objects:Statically Typed Objects as Remotely Executable QueriesBy: William Cook & Siddhartha RaiICSE 2005

Page 2: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Introduction

• Fact: Large Applications require persistence.

• Existing solutions:– EJB– Hibernate– JDO

• Problem: individual objects granularity.

Page 3: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Problems

• String encoding

• Runtime checking only

• Complex queries must be weaved by hand…

• Programmers must learn two languages.

Page 4: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

New Idea• Safe Query Objects

– Represent a query as a statically typed object. – Combine object-relational mapping with

object-oriented languages.

• We will see:– Statically typed interface to the dynamically

typed functionality in the JDO 1.0 specification.

Page 5: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

JDO Background: The Persistence Manager Interface

• Access to persistent objects via instance of the PersistenceManager interface.

• Loading individual objects:– getObjectById

• Creating a new Query:– newQuery

interface javax.jdo.PeristenceManager{Object getObjectById(Object id);Javax.jdo.Query newQuery(Class class);// methods for transactions not listed}

interface javax.jdo.PeristenceManager{Object getObjectById(Object id);Javax.jdo.Query newQuery(Class class);// methods for transactions not listed}

Page 6: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

JDO Background: The Query Interface

• Query execution is provided by the Query Interface.

interface javax.jdo.Query{void setFilter(String filter);void setOrdering(String ordering);void declareImports(String imports);void declareParameters(String params);void declareVariable(String vars);Object execute();Object execute(Object arg1);Object executeWithMap(Map parameters);// bookkeeping methods not listed}

interface javax.jdo.Query{void setFilter(String filter);void setOrdering(String ordering);void declareImports(String imports);void declareParameters(String params);void declareVariable(String vars);Object execute();Object execute(Object arg1);Object executeWithMap(Map parameters);// bookkeeping methods not listed}

Page 7: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

JDO Background: Candidate Classes

• Candidate classes:– Have structural correspondence to tables in database.

• We will use:

class Employee{ String name; float salary; Department department; Employee manager;}

class Employee{ String name; float salary; Department department; Employee manager;}

class Department{ String name; Collection<Employee> employees;}

class Department{ String name; Collection<Employee> employees;}

Page 8: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

JDO Background: Usage

Collection<Employee> execute(PersistenceManager pm){ javax.jdo.Query payCheck = pm.newQuery(Employee.class); payCheck.setFilter(“salary > maneger.salary”); Object result = payCheck.execute(); return (Collection<Employee>)result;}

Collection<Employee> execute(PersistenceManager pm){ javax.jdo.Query payCheck = pm.newQuery(Employee.class); payCheck.setFilter(“salary > maneger.salary”); Object result = payCheck.execute(); return (Collection<Employee>)result;}

The misspelled “maneger” will not be detected until runtime!

Page 9: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Safe Query• Safe query object contains:

– Filtering method– Ordering method

• Safe Query Class– Subclass of SafeQuery<T>– Instantiates RemoteQueryJDO

class PayCheck extends SafeQuery<Employee> instantiates RemoteQueryJDO{

boolean filter(Employee emp){ return emp.salary > emp.maneger.salary; }}

Candidate Class

Compilation Error

Page 10: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Filtering Method

• Defines the “WHERE” condition in the query.

• Must be called filter• Must return a boolean value.

• Free of side effects:– Must not modify states– No iterative constructs

Page 11: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Sorted Results : JDO • Queries often specify sort order for the set of

query results.• Relational query languages:

– ascending/descending order.

• Sorting in JDO:– setOrdering method.

Collection sortEmployees(){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setOrdering(“department.name ascending,”

+ “ salary descending”); return (Collection) q.execute();}

Collection sortEmployees(){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setOrdering(“department.name ascending,”

+ “ salary descending”); return (Collection) q.execute();}

Page 12: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Sorted Results: Safe Query• Safe query defines order method

– Takes a candidate object– Returns a linked list of the of sortable values.

class SortQuery instantiates RemoteQueryJDOextends SafeQuery<Employee>{

Sort order(Employee emp){ return new Sort(emp.department.name,

Sort.Direction.ASCENDING,new Sort(emp.salary,Sort.Direction.DESCENDING));

}}

class SortQuery instantiates RemoteQueryJDOextends SafeQuery<Employee>{

Sort order(Employee emp){ return new Sort(emp.department.name,

Sort.Direction.ASCENDING,new Sort(emp.salary,Sort.Direction.DESCENDING));

}}

Page 13: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Parameterized Queries: JDO

• Needed when a query behavior depends upon one or more input value.

• JDO approach:– declareParameters method

Collection salaryLimitEmployees(double limit){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setFilter(“salary > limit”); q.declareParameters(“Double limit”); Collection r = (Collection)q.execute(new Double(limit)); return r;}

Collection salaryLimitEmployees(double limit){ javax.jdo.Query q = pm.newQuery(Employee.class); q.setFilter(“salary > limit”); q.declareParameters(“Double limit”); Collection r = (Collection)q.execute(new Double(limit)); return r;}

What happens if we omit the call to declareParameters?

Page 14: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Parameterized Queries: Safe Query• Query parameters are defined as standard Java

function parameters.• Declared as arguments to the query constructor• Stored as member variables of the query object.

class SalaryLimit instantiates RemoteQueryJDOextends SafeQuery<Employee>{

double limit; /*parameter*/SalaryLimit(double limit){ this.limit = limit; }boolean filter(Employee employee){ return employee.salary > limit; }}

class SalaryLimit instantiates RemoteQueryJDOextends SafeQuery<Employee>{

double limit; /*parameter*/SalaryLimit(double limit){ this.limit = limit; }boolean filter(Employee employee){ return employee.salary > limit; }}

Page 15: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Dynamic Queries: JDO• Involve filters, parameters or sort orders• Constructed at runtime.

Collection search(String namePrefix, Double minSalary){ String filter = null; String paramDecl = “”; HashMap paramMap = new HashMap(); javax.jdo.Query q =makeQuery(Employee.class); if (namePrefix!= null){ q.declareParameters(“String namePrefix”); paramMap.put(“namePrefix”,namePrefix); filter = and(filter,”(name.startsWith(namePrefix))”); } if (minSalary != null){ q.declareParameters(“double minSalary”); paramMap.put(“minSalary”, minSalary); filter= and(filter, “(salary >= minSalary)”); } q.setFilter(filter); return q.executeWithMap(pramMap);}String and(String a, String b){…}

Collection search(String namePrefix, Double minSalary){ String filter = null; String paramDecl = “”; HashMap paramMap = new HashMap(); javax.jdo.Query q =makeQuery(Employee.class); if (namePrefix!= null){ q.declareParameters(“String namePrefix”); paramMap.put(“namePrefix”,namePrefix); filter = and(filter,”(name.startsWith(namePrefix))”); } if (minSalary != null){ q.declareParameters(“double minSalary”); paramMap.put(“minSalary”, minSalary); filter= and(filter, “(salary >= minSalary)”); } q.setFilter(filter); return q.executeWithMap(pramMap);}String and(String a, String b){…}

Page 16: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Dynamic Queries: Safe Query

class DynQuery instantiates RemoteQueryJDOextends SafeQuery<Employee>{

private String namePrefix; // may be nullprivate Double minSalary; // may be nullDynQuery (String namePrefix, Double minSalary){

this.namePrefix = namePrefix;this.minSalary = minSalary;

}boolean filter(Employee item){

return (namePrefix == null || item.name.startsWith(namePrefix)) && (minSalary == null

|| item.salary >= minSalary);}

}

class DynQuery instantiates RemoteQueryJDOextends SafeQuery<Employee>{

private String namePrefix; // may be nullprivate Double minSalary; // may be nullDynQuery (String namePrefix, Double minSalary){

this.namePrefix = namePrefix;this.minSalary = minSalary;

}boolean filter(Employee item){

return (namePrefix == null || item.name.startsWith(namePrefix)) && (minSalary == null

|| item.salary >= minSalary);}

}

Page 17: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Null Values

• Relational databases allow nullable values– Operations involving null return null

• OOP languages – Allow null object references– Problem 1: Primitive types cannot be null

• Solution: Boxing

– Problem 2: Navigation • NullPointerException treated as false returned from “filtering”• Example: or(emp.department == dept, emp.salary > min) • Solution: …

Page 18: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Implementation• The query translation is encapsulated in the RemoteQueryJDO metaclass which is applied to the safe query by the JavaOpen instantiates keyword.

• OpenJava runs the metaclass at compile time, supplying the definition of the of the query class (e.g. PayCheck) as input.

• The RemoteQueryJDO metaclass examines the user-defined filter method and generates the corresponding execute method.

Page 19: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

OpenJava

RemoteQueryJDOMetaclass

Query Class Definition

Execute Method

Compile Time

Page 20: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Advantages

• Queries defined using OO language– Static type checking– Syntax errors (at compilation time)– JDO seems more comfortable

• Observation: Most queries are either static or dynamic with static tables.– Safe query can help.

Page 21: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

Disadvantages

• Dynamic queries and data-driven with query definition loaded from DB– Open problem…

• What about creating new tables?

• Updating tables..

Page 22: Safe Query Objects: Statically Typed Objects as Remotely Executable Queries By: William Cook & Siddhartha Rai ICSE 2005

The End