Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Commitment ordering wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Entity–attribute–value model 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
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