Download Databases and Enterprise Java Beans

Document related concepts

Commitment ordering wikipedia , lookup

SQL wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

Database wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Serializability wikipedia , lookup

Relational model wikipedia , lookup

Clusterpoint wikipedia , lookup

Concurrency control wikipedia , lookup

Database model wikipedia , lookup

Versant Object Database wikipedia , lookup

Transcript
Databases and Enterprise Java Beans
Carl Nettelblad
2015-04-28
Outline
• Fixing Security
• More on Databases
• Enterprise Java Beans
Map realm roles
to application roles
• Enable check box in Security configuration: Default
Principal To Role Mapping (in Glassfish Admin
console http://localhost:4848)
– The admin console is one of those things you should
disable fully in a production environment
– Or protect
• This options makes Glassfish group names map to
security roles
• Otherwise you can specify a mapping yourself in the
separate glassfish-web.xml
Modifying queries
• Some queries do not return result rows
String query = "INSERT INTO PERSON" + "(pnr, firstname,
lastname, sex, age)" + "VALUES (1,'Eva','Svensson', 35)";
int rows = stmt.executeUpdate(query);
String query = "INSERT INTO PERSON" + "(pnr, firstname,
lastname, sex, age)" + "VALUES (1,'" + firstname +
"','Svensson', 35)";
int rows = stmt.executeUpdate(query);
Prepared statements
• Parsing SQL strings can be time-consuming
• Stored procedures
– Store complex SQL scripts in the database manager
• Prepared statements
– Give the JDBC driver a SQL string where parameter
blanks are later filled in
– Both driver and database can cache these
– Higher performance
– Separation between data and code (avoid SQL
injection)
Example, prepared statements
PreparedStatement pstmt;
pstmt = connection.prepareStatement(
"INSERT INTO PERSON (pnr,firstname,lastname,age) VALUES (?,?,?,?)");
pstmt.setInt(1, 1);
pstmt.setString(2, "Nisse");
pstmt.setString(3, "Nilsson");
pstmt.setInt(4, 37);
int x = pstmt.executeUpdate();
•
•
Note: 1-based indexing (parameters start at 1).
Why?
– Legacy history, JDBC was inspired by ODBC
– Visual Basic and other technologies in use at the time were more
likely to be 1-based
Configure a database in Java EE
• You don’t want to hardcode your connection string, or
class name
– Especially since user name and password for
database might go into the connection string
• Init parameters
– In servlet config (init-param tag/@WebInitParam
annotation)
– In server context (context-param tag)
Injection
• Classic scheme
– Configuration exists
– Imperative code to read configuration
• E.g. init method
• Confusing intent and implementation
• Instead
– Specify what you need
Example
public class MyServlet extends HttpServlet {
@Resource(name="ourdb")
private javax.sql.DataSource myDB;
}
• How to specify a data source is container-dependent
• glassfish-resources.xml
– Netbeans contains wizards for this
• Class needs to be managed by the container
– One more thing solved by Enterprise Java Beans
Connection overhead
• Database connections can be expensive
– In time, in network bandwidth, in CPU resources
– Establish TCP/IP connection
• Possibly including TLS encryption
– Authenticate
– Prepare new object on client and server
• Probably far less than 10 ms
– At most 100/s, per thread
• You might want to handle thousands of requests
• Quick responses for each user
Connection pools
• Reuse connections
• Container ensures that the connection is in a valid state
• Calls to getConnection returns a refurbished existing
connection
• Leaving data source definitions to the container
– Connection pool settings can be tuned
independently of source code
Put bottlenecks early
• Don’t let 500 request workers wait on 10 database
connections
– If every request results in a database transaction,
make the worker pool of equal or smaller size
• Why?
– Much processing will happen before you
actually get to the database
– Total load will be much worse if you let
everyone in before saying “nah, it won’t work”
• You might even want a maximum number of active
sessions
Transactions
•
•
•
•
•
What if we have multiple database queries?
UPDATE one table
SELECT in another
INSERT in a third
What if another user makes changes to one of these
tables in the meantime?
• Multiple queries are joined in a transaction
• Different isolation levels, levels of consistency
Java Transaction API
• Transaction can be manually rolled back with rollback
call on a connection
• Committed with commit call
• What if you have several data sources?
• Or what if you get an unhandled exception in the Java
code?
Managed transactions
•
•
•
•
Do the “right thing”
Roll back transaction if the processing is incomplete
Commit if request is successful
If the transaction for one participating data source is
rolled back, everything is rolled back (global
transactions)
Effects
• A transaction error can come at any time
• The transaction might last the full length of your request
– Tables or rows in the database might be locked for a
long time
– Stalling other requests
• Reordering queries might have significant effects
Effects
• “The right thing” might not be the practical thing
– Sometimes even double data sources for the same
database
• Important queries and requests, with transactions
• Reading stats etc, non-transactional
Enterprise Java Beans
• Java Beans are great
– Just write the methods you want
– Use them
Enterprise Java Beans
• Plain Java Beans are horrendous
– How should the servlet know what bean to use?
• Generalize by interfaces
• But how do we find the correct implementation?
• Packaging/distribution
– No reuse of instances
– No relation to container-managed resources
– No relation to container-managed security
– No general solution for remote access
• These are the reasons to have EJBs
What is an EJB?
• A server-side Java component encapsulating business
logic for an application
– This is true for a Java bean running on our server as
well
• Additionally
– It fulfills certain criteria and is used through the
container
Important reasons to use EJBs
• Scalability
– Distributed environment
– Some EJBs might reside on other servers
– Minimize overhead without engineering your own
solutions
• Beans participating in transactions
• Multiple clients/multiple possible implementations
• Access control
Different types of
enterprise beans
• Session beans
– Implementing a service through method calls
– Session is not the same as “session” in servlet/JSP
• Message-driven beans
– Listener in the Java Message Service API
• Implementing logic asynchronously
• Entity beans
– Containing representation of business data
• Replaced by JPA
Session bean
• Workflow
– Client asks for session bean
• Bean session starts
– Calls method(s)
• Bean not thread reentrant, only used by that
client at that point
– Client use ends
• Bean session ends
• Object is discarded or reused
Stateful session beans
• Stateful session beans
– Any information on the current client can be stored in
instance variables etc
• The result of a method call is dependent can be
dependent on a previous call
– Dependent on the same object instance being used
during the session
• Example:
bean.makeQuery(queryData);
ArrayList list = bean.getResults();
Stateless session beans
• Stateless session beans do not save state in the
instances
– Each method call from a client is atomistic
– Any instance of the bean should give the same
response
• Example:
ArrayList list =
bean.getQueryResults(queryData);
• Might give less nice object-oriented design
– (Much) better scaling
– Especially when we get to web services
Stateless means client state
• Stateless session beans contains no client state in
instance variables
• Can contain reusable service connections or other
variables
• Only a single method is called at a time on the same
instance
Stateful vs. stateless
• Stateful makes sense if
– The point is to maintain a multistep service
interaction
– Information needs to be saved per-client between
method calls (expensive per-client state)
– The bean is a middleware between the client and
other complex services
– The bean is a coordinator of workflow for several
more restricted beans
Stateless beans
• Anytime stateful is not needed, especially:
– No needs for client-specific data
– Each method call is naturally atomistic and identical
for all clients, “send an e-mail”, “create a file”,
“perform a calculation”
– High-volume read-only retrieval of data
Singleton beans
• Single global instance
• Might be harder to scale if you rely on this fact
– I.e. state that has to be synchronized
• Your client doesn’t need to know whether your bean is
actually stateful, stateless or singleton
• Specify “concurrency type”
– BEAN – the bean can accept multiple calls
– CONTAINER – the container will make concurrent
calls serial
Message-driven beans
• Java Message Service API
• Sending and receiving messages rather than method
calls
• A message-driven bean consumes messages
• Delivery and processing can be guaranteed
– Doesn’t need to happen synchronously
• Example: User places an order
– The order dispatch bean picks up the message of
the order
How do you implement a bean?
• Old structure
– Home interface
• Interfaces related to managing bean lifecycle
(create/destroy etc)
– Business interface
• Actual methods
• Two versions
– For remote calls and immediate calls
• Remote and local versions
– EJBs started out as “always remote”, too slow
in many cases
How is remoting different?
• All object parameters are serialized
– Object representation is saved and reconstructed in
the other JVM
• This breaks pass-by-reference semantics
• You are not teleporting your parameter objects away to
another JVM and then getting it back
– You are just sending a clone which is then killed
The old structure
• Your bean class should actually not implement the
bean interfaces in the old standard
– Only implement SessionBean interface etc
• Hard to keep method signatures synchronized
The “new” structure (EJB 3)
• Real interfaces
• Annotation @Local or @Remote on interface main way
to designate local or remote usage
– Implement the interface to create a bean
– The bean class and interface can in theory be used
outside the container
• Additional annotations @Stateless, @Stateful etc
• Just like with servlets, some metadata for EJBs can
also be specified in a XML file
– The deployment descriptor
– Create an empty example in Netbeans to see this
Injection
• We used the @Resource tag for data source injection in
servlets
• We can use the @EJB tag for injecting EJBs
• If there is only a single implementation of an interface,
it’s enough to write
@WebServlet….
public class… {
@EJB
private MySessionBeanInterface someVariableName;
}
More injection
• You can be explicit and specify a name (also specified
in deployment descriptor
– @EJB(beanName="nameOfBean")
– Can be matched by
@Stateless(name="nameOfBean") in bean class
• The point is that you can switch to another bean
implementation using configuration
Accessing databases in EJBs
• @Resource didn’t work in plain Java beans
– The container won’t create the objects, so it can’t
inject into them
• It does work for EJBs
• The EJB will automatically participate in transaction
management
@TransactionAttribute
• Different attitudes towards transactions:
– Mandatory – throw exception if no transaction is not already
going
– Never – throw exception IF a transaction is already going
– Not supported – if there is a transaction, don’t participate in it,
do outside transactions
– Required – use existing transaction, if no existing, create new
– Requires new – create a separate transaction, even if there is
one
– Supports – use transaction if and only if it exists
• “Required” is the default
• Not supported and Requires new can reduce overhead
– Put big write operations in separate or no transactions
Security in EJBs
• Declarative security goes to EJBs as well
• @PermitAll
• @DenyAll
– Specified on method or class to override defaults
• @RolesAllowed
– Specify role names that are allowed to call the
method
Accessing the SessionContext
• The session context gives you additional information for
a session bean
• Cleanest modern way to access
private @Resource SessionContext ctx;
Method calls isCallerInRole, getCallerPrincipal
Starting a transaction
in the servlet
• Transaction not started if not accessing any resource
• You might want to
// We want to start transactions from client: get UserTransaction
UserTransaction utx = null;
try {
utx = (UserTransaction) initialContext.lookup("java:comp/UserTransaction");
} catch (Exception e) {
out.println("<li>Cannot lookup java:comp/UserTransaction: " + e + "</li>");
return;
}
try {
utx.begin();
/* Operations go here */
utx.commit();
} catch (Exception e) {
utx.rollback(); // Container should do this for us, really
throw e;
}
Object-relational mapping
and JPA
• The object-oriented world and the relational world are
similar, yet different
– Objects are separate entities
• Inheritance, references to other objects in many
ways
• Easy to represent trees and other graphs
– Relational databases are based on tables
• All rows have the same structure
• Closely tied to the table
• Fixed relations between tables
• (Graphs through self-relations)
Objects and tables
• Different data types
• Still, quite common to create a Java Bean/”value
object” to represent the content of a table row
• Risk of writing lots of “braindead” CRUD code
– CReate
– Update
– Delete
• Separate methods for each bean class, mapping to
each table
– High risk of manual errors
Another way
• What if we could say which fields in a class map to
which columns in a table?
– And how references to other classes map to
database relations
• Even create the database schema from our classes
• This is the foundation of object-relational mapping
• Java Persistence API is one way to do it
Two views on JPA
• Convenient way to model the database structure as
Java classes
– Using Java as a tool to interact with the database
• Convenient way to persist Java objects permanently
and with transaction safety
– Using the database as a tool for our application
Components in JPA
• An API
• A query language
• Metadata for the object/relational mapping
• Contains a service provide interface
– Different databases or other resources can provide
this interface
– Your code can easily move
– Not necessarily easy to move existing data…
Components in JPA
• Persistence providers
– Default provider in Java EE 6
– Other providers do exist
How to map classes to tables?
• Same old story
– Annotations vs. XML
• One or the other
– Do you want to map the same Java classes to
different database schemas?
• Go for XML
– Is the mapping fixed?
• Go for annotations
A POJO Java bean
public class
private
private
private
...
}
BankAccount {
String accountID;
String ownerName;
double balance;
• The account ID is the primary key.
JPA entities
• Entities are the persistent data objects in our
application
– Can be only fields of primitive types
– Can be more complex
• Each entity has a well-defined identity, key that can be
used to retrieve it (primary key in DB)
• Their state is exposed
• They are not remote-accessible
• Entities are supposed to live on beyond shutdown of
the application
Example
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Account implements Serializable {
/** The account number is the primary key for the persistent object */
@Id
public int accountNumber;
public String ownerName;
public int balance;
/**
* Entities must have a public no-arg constructor
*/
public Account() {
// auto-generation
accountNumber = (int) System.nanoTime();
}
Example
public void deposit(int amont) {
balance += amount,
}
public int withdraw(int amount) {
if (amount > balance) {
return 0;
else {
balance -= amount;
return amount;
}
}
Comments
• If field names map to column names and class names
map to table names, nothing else is needed
• Configuration will determine whether schema is autocreated
– Property
javax.persistence.schema-generation.database.action
with values none, create, drop-and-create, drop
– Dropping means removing everything
– Good for testing from a blank slate
– Dangerous anywhere close to production data
persistence.xml
• Configuration for the JPA services
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="unit1">
<jta-data-source>mydb</jta-data-source>
<non-jta-data-source>mydb-nontrans</jta-data-source>
<properties>
<property name="eclipselink.target-database"
value="JavaDB"/>
</properties>
</persistence-unit>
</persistence>
Explanation
• The data source
– With transaction management
– Without transaction management
• Specify SQL “dialect”
– Derby in this case
Entity manager
• Entry point for managing persistence
• Interaction with data source, transactions
Example methods
• Query for objects (find/query)
– Query on ID or query using EB-QL
• Update object based on state of constructed object
– New object persist
– Existing objects merge
• detach managed entities to become regular objects
• remove entities (from persistence)
• refresh entity based on current database state (as
seen within transaction)
Stateless EJB example
package examples.entity.intro;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.Remote;
import javax.persistence.*;
/**
* Stateless session bean facade for account entities,
* remotely accessible
*/
@Stateless
@Remote(Bank.class)
public class BankBean implements Bank {
/**
* The entity manager object, injected by the container
*/
@PersistenceContext
private EntityManager manager;
public List<Account> listAccounts() {
Query query = manager.createQuery("SELECT a FROM Account a");
return query.getResultList();
}
Stateless EJB example
public Account openAccount(String ownerName) {
Account account = new Account();
account.ownerName = ownerName;
manager.persist(account);
return account;
}
public int getBalance(int accountNumber) {
Account account = manager.find(
Account.class, accountNumber);
return account.balance;
}
public void deposit(int accountNumber, int amount) {
Account account = manager.find(Account.class, accountNumber);
account.deposit(amount);
}
}
}
Stateless EJB example
public int withdraw(int accountNumber, int amount) {
Account account = manager.find(Account.class, accountNumber);
return account.withdraw(amount);
}
public void close(int accountNumber) {
Account account = manager.find(Account.class, accountNumber);
manager.remove(account);
}
}
Conclusion
• JPA allows you to write code almost like you were just
using Java objects
– Code focusing on intent
• The Java EE framework will handle many aspects
• You can still run into unexpected failed transactions
due to e.g. locking
• There are several implementations of JPA
– One is the Java ORM library Hibernate (which
predates the JPA standard)
Summary
• Role-based authorization
– Using container services, in servlets and EJBs
• Databases
– Crash course in SQL
• Connecting to databases
– Using container services
• The concept of injection
• EJBs, primarily stateful, stateless session beans
• JPA