diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..c31c2f2 Binary files /dev/null and b/.DS_Store differ diff --git a/pom.xml b/pom.xml index 9187e9a..ed35e7a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.revature - Pi2a1000Places + Pi1000Places 1.0-SNAPSHOT war @@ -14,101 +14,77 @@ 8 - - - - + + + + + + + + + + + + + + + + + + + + - org.apache.tomcat.maven - tomcat7-maven-plugin - 2.2 - - http://localhost:8080/manager/text - LocalTomcat - /PitoA1000Places - true - + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + com.microsoft.azure + azure-webapp-maven-plugin + 2.2.0 + + + v2 + + + 9cc4b7e1-da29-4fd8-8ac8-1e56252688f4 + + sqldatabase + + PitoA1000Places + + East US + + + windows + 1.8 + tomcat 9.0 + + + + + ${project.basedir}/target + + *.war + + + + + + B1 + + + - + @@ -128,58 +104,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + + + com.microsoft.azure + azure-webapp-maven-plugin + 2.2.0 + + + v2 + + + 005be574-60e2-49d1-8b2c-172a8a71c4a6 + + project + + Pi1000 + + West US + + + windows + 1.8 + tomcat 9.0 + + + + + ${project.basedir}/target + + *.war + + + + + + B1 + + + + @@ -213,13 +189,6 @@ provided - - - com.fasterxml.jackson.core - jackson-databind - 2.13.2.2 - - com.fasterxml.jackson.core @@ -240,20 +209,7 @@ mssql-jdbc 10.2.1.jre8 - - org.junit.jupiter - junit-jupiter-api - 5.8.2 - test - - - - org.junit.jupiter - junit-jupiter-api - 5.8.2 - test - - + \ No newline at end of file diff --git a/src/main/java/com/revature/Pi2a1000Places/auth/AuthServlet.java b/src/main/java/com/revature/Pi2a1000Places/auth/AuthServlet.java index fe11c7b..3d1bcbe 100644 --- a/src/main/java/com/revature/Pi2a1000Places/auth/AuthServlet.java +++ b/src/main/java/com/revature/Pi2a1000Places/auth/AuthServlet.java @@ -6,6 +6,7 @@ import com.revature.Pi2a1000Places.util.exceptions.AuthenticationException; import com.revature.Pi2a1000Places.util.exceptions.InvalidRequestException; + import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; diff --git a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCard.java b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCard.java index f5f6717..6de84dc 100644 --- a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCard.java +++ b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCard.java @@ -1,20 +1,34 @@ package com.revature.Pi2a1000Places.creditcard; +import javax.persistence.*; + +@Entity +@Table (name = "credit_card") public class CreditCard { - //CC value setup - initializing + + @Id + @Column(name="cc_number") + @GeneratedValue(strategy= GenerationType.AUTO) private String ccNumber; + //CC value setup - initializing + @Column (name= "cc_Name") private String ccName; + @Column (name= "cvv") private int cvv; + @Column (name="exp_Date") private String expDate; + @Column (name ="zip") private int zip; + @Column (name ="limit") private int limit; + @Column (name ="user_Name") private String userName; -//Creating Constructors for the CC Class +//CC Class Constructors public CreditCard(String ccNumber, String ccName, int cvv, String expDate, int zip, int limit, String userName) { - this.ccNumber = ccNumber; + this.ccName = ccName; this.cvv = cvv; this.expDate = expDate; diff --git a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDao.java b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDao.java index 01d5816..6808300 100644 --- a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDao.java +++ b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDao.java @@ -1,88 +1,94 @@ package com.revature.Pi2a1000Places.creditcard; -import com.revature.Pi2a1000Places.creditcard.CreditCardServices; -import com.revature.Pi2a1000Places.util.ConnectionFactory; import com.revature.Pi2a1000Places.util.HibernateUtil; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; -import com.revature.Pi2a1000Places.util.HibernateUtil; - import java.io.IOException; -public class CreditCardDao extends CreditCardServices { +public class CreditCardDao { //Create creditCard public static CreditCard create(Object CreditCard) { - CreditCard creditcard = new CreditCard(); - creditcard.setCCNumber("7878"); - creditcard.setCCName("Test"); - creditcard.setCvv(Integer.parseInt("888")); - creditcard.setExpDate("12/12/28"); - creditcard.setZip(Integer.parseInt("64646")); - creditcard.setLimit(Integer.parseInt("55000")); - creditcard.setUserName("Name"); + CreditCard creditcard = new CreditCard(); + creditcard.setCCNumber("7878"); + creditcard.setCCName("Test"); + creditcard.setCvv(Integer.parseInt("888")); + creditcard.setExpDate("12/12/28"); + creditcard.setZip(Integer.parseInt("64646")); + creditcard.setLimit(Integer.parseInt("55000")); + creditcard.setUserName("Name"); - try { - SessionFactory sessionFactory = HibernateUtil.getSession().getSessionFactory(); - Session session = sessionFactory.openSession(); - session.beginTransaction(); - session.save(CreditCard); - return new CreditCard(); - session.getTransaction().commit(); - }catch (HibernateException){ - } catch (IOException e) { - throw new RuntimeException(e); + try { + SessionFactory sessionFactory = HibernateUtil.getSession().getSessionFactory(); + Session session = sessionFactory.openSession(); + session.beginTransaction(); + session.save(CreditCard); + session.getTransaction().commit(); + return new CreditCard(); + } catch (HibernateException | IOException e) { + throw new RuntimeException(e); + } finally { + HibernateUtil.closeSession(); + } } - System.out.println("CC Added"); - return null; - session.close(); - sessionFactory.close(); - { + //Update creditCard + public boolean update(CreditCard updatedCreditCard) { -// //Update creditCard -// public boolean update(CreditCard updatedCreditCard){ -// -// Session session; + Session session; + try { + session = (Session) HibernateUtil.getSession().getSessionFactory(); + Transaction transaction = session.beginTransaction(); + session.update(updatedCreditCard); + + //creditCard.setCCName() ("Test") + session.getTransaction().commit(); + return true; + } catch (HibernateException | IOException e) { + + System.out.println("CC Updated"); + return false; + } finally { + HibernateUtil.closeSession(); + } + + //create follow-up method for updating credit cards (Hibernate-format calls for x2) + //How to ensure CC record is replaced after update, not stored in database? // try { -// sessionFactory = HibernateUtil.getSession().getSessionFactory(); -// session = sessionFactory.openSession(); -// session.beginTransaction(); -// session.update(creditcard); -// return updatedCreditCard; -// //creditCard.setCCName() ("Test") +// session = (Session) HibernateUtil.getSession().getSessionFactory(); +// Transaction transaction = session.beginTransaction(); +// session.cut(CreditCard); // session.getTransaction().commit(); -// } catch (HibernateException) { -// } catch (IOException e) { -// throw new RuntimeException(e); +// return true; +// } catch (HibernateException | IOException e) { // // System.out.println("CC Updated"); -// return CreditCard; -// session.close(); -// sessionFactory.close(); -// //where does return statement go? +// return false; +// } finally { +// HibernateUtil.closeSession(); +// } - } + } - //Delete creditCard - public Boolean delete (String ccNumber){ + //Delete creditCard + public Boolean delete(String userName) { try { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); - CreditCard creditCard = session.load(CreditCard.class,"creditCard"); - session.delete(creditCard); + CreditCard creditCard = session.load(CreditCard.class, "creditCard"); + session.delete(creditCard); transaction.commit(); + return true; } catch (HibernateException | IOException e) { System.out.println("CC Deleted"); + return false; } finally { HibernateUtil.closeSession(); } - } - - + } } // MVP a. Create - ADD Card @@ -141,28 +147,4 @@ public Boolean delete (String ccNumber){ // //// d. Pay off your balance with your credit card > Update (to the limit) ////4.5 (for credit card update and update limit see do get in trainer servlet ) -//} - - public void update () { - } - - public void update () { - } - - public void update () { - } - - public static void create () { - } - - public static void createCC () { - } - - public static void createCC () { - } - - public static void createCC () { - } - - public static void createCC () { - } \ No newline at end of file +//} \ No newline at end of file diff --git a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDto.java b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDto.java index 3e08c20..0216336 100644 --- a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDto.java +++ b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardDto.java @@ -10,7 +10,8 @@ public class CreditCardDto { private String expDate; private String zip; private String limits; - private String customerUsername; + private String userName; + private CreditCard String; public String getCcNumber() { return ccNumber; @@ -60,11 +61,16 @@ public void setLimits(String limits) { this.limits = limits; } - public String getCustomerUsername() { - return customerUsername; + public String getUserName() { + String UserName = null; + return UserName; } + + public void setUsername(String username) { + String UserName = new String(); + this.userName = UserName; } - public void setCustomerUsername(String customerUsername) { - this.customerUsername = customerUsername; + public CreditCard getCreditCard() { + return String; } } diff --git a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServices.java b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServices.java index 75bb946..9978083 100644 --- a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServices.java +++ b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServices.java @@ -1,27 +1,20 @@ package com.revature.Pi2a1000Places.creditcard; -import javax.persistence.Entity; -import javax.persistence.Table; - -import java.io.Serializable; - -import javax.persistence.*; - public class CreditCardServices { private final CreditCardDao creditCardDao; - @Id - @Column(name="CCNUMBER") - @GeneratedValue(strategy=GenerationType.AUTO) - private int ccNumber; + public CreditCardServices(CreditCardDao creditCardDao) { + this.creditCardDao = creditCardDao; + } //@Override - public CreditCard create(CreditCard newCreditCard){ + public CreditCard create(CreditCard newCreditCard) { return creditCardDao.create(new CreditCard()); } + //@Override public CreditCard update(CreditCard updatedCreditCard) { - if (creditCardDao.update(updatedCreditCard)) return null; + if (!creditCardDao.update(updatedCreditCard)) return null; return updatedCreditCard; } @@ -31,24 +24,9 @@ public boolean delete() { return delete(null); } - // Override - public boolean delete(String ccNumber){ + // Override + public boolean delete(String userName) { return true; } - - - @Column(name="CCNAME") - private String ccName; - @Column(name="CVV") - private int cVv; - @Column(name="EXPDATE") - private String expDate; - @Column(name="ZIP") - private int zip; - @Column(name="LIMIT") - private String limit; - @Column(name="USERNAME") - private String userName; - } \ No newline at end of file diff --git a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServlet.java b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServlet.java index fe45961..2c052f9 100644 --- a/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServlet.java +++ b/src/main/java/com/revature/Pi2a1000Places/creditcard/CreditCardServlet.java @@ -1,7 +1,6 @@ package com.revature.Pi2a1000Places.creditcard; import com.fasterxml.jackson.databind.ObjectMapper; -import com.revature.Pi2a1000Places.auth.LoginCreds; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -9,14 +8,17 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; -public class CreditCardServlet extends HttpServlet{ - Private final ObjectMapper mapper; - private final CreditCardDao creditCardDao; +public class CreditCardServlet extends HttpServlet { + private final ObjectMapper mapper; + private final CreditCardServices creditCardServices; - public CreditCardServlet(ObjectMapper mapper) { + public CreditCardServlet(ObjectMapper mapper, CreditCardServices creditCardServices) { this.mapper = mapper; + this.creditCardServices = creditCardServices; + } + protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doOptions(req, resp); resp.addHeader("Access-Control-Allow-Origin", "*"); @@ -25,32 +27,29 @@ protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throw } - //CREATE + //CREATE- Allows servlet to handle POST request + // ** Sending information to the server like HTML form data protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { // addHeads(req, resp); resp.addHeader("Access-Control-Allow-Origin", "*"); resp.addHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE"); resp.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); CreditCardDto pass = mapper.readValue(req.getInputStream(), CreditCardDto.class); - CreditCard firstResult = CreditCardDao.createCC(pass.getCcNumber(), pass.getCcName(), pass.getCvv(), pass.getExpDate(), pass.getZip(), pass.getLimits(), pass.getCustomerUsername()); - CreditCard theObject = CreditCardDao.followUpCreateCreditCard(pass.getCcNumber()); - String payload = mapper.writeValueAsString(theObject); resp.getWriter().write("Credit Card Added \n"); resp.getWriter().write(payload); resp.setStatus(201); } - // UPDATE + // UPDATE protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.addHeader("Access-Control-Allow-Origin", "*"); resp.addHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE"); resp.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); CreditCardDto pass = mapper.readValue(req.getInputStream(), CreditCardDto.class); - CreditCard firstResult = creditCardDao.update(pass.getTableSelection(), pass.getNewCellName(), pass.getCcNumber()); - CreditCard theObject = creditCardDao.update(pass.getCcNumber()); + CreditCard theObject = creditCardServices.update(pass.getCreditCard()); String payload = mapper.writeValueAsString(theObject); @@ -63,9 +62,9 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.addHeader("Access-Control-Allow-Origin", "*"); resp.addHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE"); - resp.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); CreditCardDto pass = mapper.readValue(req.getInputStream(), CreditCardDto.class); - - boolean deleteTrue = creditCardDao.delete(pass.getCcNumber()); + resp.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); + CreditCardDto pass = mapper.readValue(req.getInputStream(), CreditCardDto.class); + boolean deleteTrue = creditCardServices.delete(); String payload = mapper.writeValueAsString(deleteTrue); @@ -73,6 +72,4 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws resp.getWriter().write(payload); resp.setStatus(201); } - - } diff --git a/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServices.java b/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServices.java index 9ea2b08..a609906 100644 --- a/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServices.java +++ b/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServices.java @@ -2,7 +2,6 @@ import com.revature.Pi2a1000Places.util.exceptions.AuthenticationException; import com.revature.Pi2a1000Places.util.exceptions.InvalidRequestException; - public class CustomerServices { private CustomerDao customerDao = new CustomerDao(); @@ -75,7 +74,7 @@ public String deleteCustomer(Customer customerToDelete){ return deleteStatement ; } - public Customer updateCustomer(Customer customerToUpdate){ + public int updateCustomer(Customer customerToUpdate){ String customerName = customerToUpdate.getModName(); System.out.println("modName: " + modName); String creatorName = customerToUpdate.getCreatorName(); diff --git a/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServlet.java b/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServlet.java index 6beb942..14aebe3 100644 --- a/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServlet.java +++ b/src/main/java/com/revature/Pi2a1000Places/customer/CustomerServlet.java @@ -1,9 +1,11 @@ package com.revature.Pi2a1000Places.customer; import com.fasterxml.jackson.databind.ObjectMapper; + import com.revature.Pi2a1000Places.auth.LoginCreds; import com.revature.Pi2a1000Places.util.exceptions.AuthenticationException; import com.revature.Pi2a1000Places.util.exceptions.InvalidRequestException; +import com.revature.Pi2a1000Places.util.interfaces.Authable; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; diff --git a/src/main/java/com/revature/Pi2a1000Places/menu/Menu.java b/src/main/java/com/revature/Pi2a1000Places/menu/Menu.java index 0a8238c..79be890 100644 --- a/src/main/java/com/revature/Pi2a1000Places/menu/Menu.java +++ b/src/main/java/com/revature/Pi2a1000Places/menu/Menu.java @@ -1,8 +1,75 @@ package com.revature.Pi2a1000Places.menu; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "menu") public class Menu { - public static class MenuServices { - } +@Id + private String menuItem; + + private int cost; + + private String protein; + + private String isSubstitutable; + + public Menu(String menuItem, int cost, String protein, String isSubstitutable) { + super(); + this.menuItem = menuItem; + this.cost = cost; + this.protein = protein; + this.isSubstitutable = isSubstitutable; + + } + public Menu() { + + } + + public String getMenuItem() { + return menuItem; + } + + public void setMenuItem(String menuItem) { + this.menuItem = menuItem; + } + + public int getCost() { + return cost; + } + + public void setCost(int cost) { + this.cost = cost; + } + + public String getProtein() { + return protein; + } + + public void setProtein(String protein) { + this.protein = protein; + } + + public String getSubstitutable() { + return isSubstitutable; + } + + public void setSubstitutable(String substitutable) { + isSubstitutable = substitutable; + } + + @Override + public String toString() { + return "Menu{" + + "menuItem='" + menuItem + '\'' + + ", cost=" + cost + + ", protein='" + protein + '\'' + + ", isSubstitutable=" + isSubstitutable + + '}'; } +} diff --git a/src/main/java/com/revature/Pi2a1000Places/order/OrderServlet.java b/src/main/java/com/revature/Pi2a1000Places/order/OrderServlet.java index 413744f..edff0cc 100644 --- a/src/main/java/com/revature/Pi2a1000Places/order/OrderServlet.java +++ b/src/main/java/com/revature/Pi2a1000Places/order/OrderServlet.java @@ -1,10 +1,7 @@ package com.revature.Pi2a1000Places.order; import com.fasterxml.jackson.databind.ObjectMapper; -import com.revature.Pi2a1000Places.customer.Customer; -import com.revature.Pi2a1000Places.order.*; import com.revature.Pi2a1000Places.auth.LoginCreds; -import com.revature.Pi2a1000Places.util.exceptions.AuthenticationException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; diff --git a/src/main/java/com/revature/Pi2a1000Places/util/HibernateUtil.java b/src/main/java/com/revature/Pi2a1000Places/util/HibernateUtil.java index 7b683a7..a25547f 100644 --- a/src/main/java/com/revature/Pi2a1000Places/util/HibernateUtil.java +++ b/src/main/java/com/revature/Pi2a1000Places/util/HibernateUtil.java @@ -1,16 +1,16 @@ package com.revature.Pi2a1000Places.util; +import com.revature.Pi2a1000Places.creditcard.CreditCard; import com.revature.Pi2a1000Places.customer.Customer; -import com.revature.Pi2a1000Places.credit_card.CreditCard; import com.revature.Pi2a1000Places.menu.Menu; import com.revature.Pi2a1000Places.order.Order; - import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; -import org.hibernate.service.ServiceRegistry; +import javax.imageio.spi.ServiceRegistry; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.Configuration; import java.io.IOException; import java.util.Properties; @@ -20,8 +20,13 @@ public class HibernateUtil { private static Session session; public static Session getSession() throws IOException { - if(sessionFactory == null) { - Configuration configuration = new Configuration(); + if (sessionFactory == null) { + Configuration configuration = new Configuration() { + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) { + return new AppConfigurationEntry[0]; + } + }; Properties props = new Properties(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); @@ -30,25 +35,20 @@ public static Session getSession() throws IOException { configuration.setProperties(props); configuration.addAnnotatedClass(Customer.class); + configuration.addAnnotatedClass(CreditCard.class); + configuration.addAnnotatedClass(Menu.class); + configuration.addAnnotatedClass(Order.class); - //configuration.addAnnotatedClass(CreditCard.class); - //configuration.addAnnotatedClass(Menu.class); - //configuration.addAnnotatedClass(Order.class); - - - // ServiceRegistry ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); - - } - if(session == null) { + if (session == null) { session = sessionFactory.openSession(); } @@ -60,13 +60,29 @@ public static void closeSession() { session = null; } -} - -// hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -// hibernate.connection.driver_class=org.postgresql.Driver -// hibernate.connection.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=restaurant -// hibernate.connection.username=postgres -// hibernate.connection.password= -// hibernate.show_sql=true -// #Create once and update thereafter -// hibernate.hbm2ddl.auto=update \ No newline at end of file + + //See Lecture 5/27/2022 @21 minutes (added 6/4/22)- Azure App Configurations + //Deploy via terminal (all 10 lines), then sign into acct + + String url = system.getenv(SQLAZURECONNSTR Pito1000DB); + String username = system.getenv(name: "Dbuser") + String password = system.getenv(password: "Dbpassword") + + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.url", url); + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.username", username); + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.password", password); + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.hibernate.dialect", "org.hibernate.dialect.SQLServerDialect"); + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver"); + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.hibernate.show_sql", "true"); + configuration.setCurrentTenantIdentifierResolver("hibernate.connection.hibernate.hbm2ddl.auto", "update"); + + + + hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + hibernate.connection.driver_class=org.postgresql.Driver + hibernate.connection.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=restaurant + hibernate.connection.username=postgres + hibernate.connection.password= + hibernate.show_sql=true + #Create once and update thereafter + hibernate.hbm2ddl.auto=update \ No newline at end of file diff --git a/src/main/java/com/revature/Pi2a1000Places/util/web/ContextLoaderListener.java b/src/main/java/com/revature/Pi2a1000Places/util/web/ContextLoaderListener.java index 6bc02bb..0ec4f01 100644 --- a/src/main/java/com/revature/Pi2a1000Places/util/web/ContextLoaderListener.java +++ b/src/main/java/com/revature/Pi2a1000Places/util/web/ContextLoaderListener.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.revature.Pi2a1000Places.auth.AuthServlet; +import com.revature.Pi2a1000Places.creditcard.CreditCardDao; +import com.revature.Pi2a1000Places.creditcard.CreditCardServlet; import com.revature.Pi2a1000Places.customer.CustomerDao; import com.revature.Pi2a1000Places.customer.CustomerServices; import com.revature.Pi2a1000Places.customer.CustomerServlet; @@ -16,23 +18,26 @@ @WebListener public class ContextLoaderListener implements ServletContextListener { + private ObjectMapper creditCardDao; + @Override public void contextInitialized(ServletContextEvent sce) { ObjectMapper mapper = new ObjectMapper(); CustomerDao customerDao = new CustomerDao(); CustomerServices customerServices = new CustomerServices(); OrderServices orderServices = new OrderServices(); + CreditCardDao creditCardDao = new CreditCardDao(); AuthServlet authServlet = new AuthServlet(customerServices, mapper); CustomerServlet customerServlet = new CustomerServlet(customerServices, mapper); OrderServlet orderServlet = new OrderServlet(orderServices, mapper); - + CreditCardServlet creditCardServlet = new CreditCardServlet(creditCardDao); ServletContext context = sce.getServletContext(); context.addServlet("AuthServlet", authServlet).addMapping("/auth"); context.addServlet("CustomerServlet", customerServlet).addMapping("/customers/*"); context.addServlet("OrderServlet", orderServlet ).addMapping("/orders/*"); - + context.addServlet("CreditCardServlet", creditCardServlet).addMapping("/creditCard/*"); } diff --git a/src/main/webapp/WEB-INF/index.html b/src/main/webapp/WEB-INF/index.html new file mode 100644 index 0000000..c9aca0b --- /dev/null +++ b/src/main/webapp/WEB-INF/index.html @@ -0,0 +1,1397 @@ + + + + + + + +Hibernate Getting Started Guide + + + + + + +
+
+

Preface

+
+
+

Working with both Object-Oriented software and Relational Databases can be cumbersome and time-consuming. +Development costs are significantly higher due to a number of "paradigm mismatches" between how data is represented in objects +versus relational databases. Hibernate is an Object/Relational Mapping (ORM) solution for Java environments. The +term Object/Relational Mapping refers to the technique of mapping data between an object model representation to +a relational data model representation. See http://en.wikipedia.org/wiki/Object-relational_mapping for a good +high-level discussion. Also, Martin Fowler’s OrmHate article +takes a look at many of the mismatch problems.

+
+
+

Although having a strong background in SQL is not required to use Hibernate, having a basic understanding of the +concepts can help you understand Hibernate more quickly and fully. An understanding of data modeling principles +is especially important. Both http://www.agiledata.org/essays/dataModeling101.html and +http://en.wikipedia.org/wiki/Data_modeling are good starting points for understanding these data modeling +principles. If you are completely new to database access in Java, +https://www.marcobehler.com/guides/a-guide-to-accessing-databases-in-java contains a good overview of the various parts, +pieces and options.

+
+
+

Hibernate takes care of the mapping from Java classes to database tables, and from Java data types to SQL data +types. In addition, it provides data query and retrieval facilities. It can significantly reduce development +time otherwise spent with manual data handling in SQL and JDBC. Hibernate’s design goal is to relieve the +developer from 95% of common data persistence-related programming tasks by eliminating the need for manual, +hand-crafted data processing using SQL and JDBC. However, unlike many other persistence solutions, Hibernate +does not hide the power of SQL from you and guarantees that your investment in relational technology and +knowledge is as valid as always.

+
+
+

Hibernate may not be the best solution for data-centric applications that only use stored-procedures to +implement the business logic in the database, it is most useful with object-oriented domain models and business +logic in the Java-based middle-tier. However, Hibernate can certainly help you to remove or encapsulate +vendor-specific SQL code and streamlines the common task of translating result sets from a tabular +representation to a graph of objects.

+
+
+

See http://hibernate.org/orm/contribute/ for information on getting involved.

+
+
+ + + + + +
+ + +The projects and code for the tutorials referenced in this guide are available as hibernate-tutorials.zip +
+
+
+
+
+

1. Obtaining Hibernate

+
+
+

1.1. The Hibernate Modules/Artifacts

+
+

Hibernate’s functionality is split into a number of modules/artifacts meant to isolate dependencies (modularity).

+
+
+
+
hibernate-core
+
+

The main (core) Hibernate module. Defines its ORM features and APIs as well as the various integration SPIs.

+
+
hibernate-envers
+
+

Hibernate’s historical entity versioning feature

+
+
hibernate-spatial
+
+

Hibernate’s Spatial/GIS data-type support

+
+
hibernate-osgi
+
+

Hibernate support for running in OSGi containers.

+
+
hibernate-agroal
+
+

Integrates the Agroal connection pooling library into Hibernate

+
+
hibernate-c3p0
+
+

Integrates the C3P0 connection pooling library into Hibernate

+
+
hibernate-hikaricp
+
+

Integrates the HikariCP connection pooling library into Hibernate

+
+
hibernate-vibur
+
+

Integrates the Vibur DBCP connection pooling library into Hibernate

+
+
hibernate-proxool
+
+

Integrates the Proxool connection pooling library into Hibernate

+
+
hibernate-jcache
+
+

Integrates the JCache caching specification into Hibernate, +enabling any compliant implementation to become a second-level cache provider.

+
+
hibernate-ehcache
+
+

Integrates the Ehcache caching library into Hibernate as a second-level cache provider.

+
+
+
+
+
+

1.2. Release Bundle Downloads

+
+

The Hibernate team provides release bundles hosted on the SourceForge File Release System, in both +TGZ and ZIP formats. Each release bundle contains JAR files, documentation, source code, and other goodness.

+
+
+

You can download releases of Hibernate, in your chosen format, from the list at +https://sourceforge.net/projects/hibernate/files/hibernate-orm/. The release bundle is structured as follows:

+
+
+
    +
  • +

    The lib/required/ directory contains the hibernate-core jar and all of its dependencies. All of these jars are +required to be available on your classpath no matter which features of Hibernate are being used.

    +
  • +
  • +

    The lib/envers directory contains the hibernate-envers jar and all of its dependencies (beyond those in +lib/required/ and lib/jpa/).

    +
  • +
  • +

    The lib/spatial/ directory contains the hibernate-spatial jar and all of its dependencies (beyond those in lib/required/)

    +
  • +
  • +

    The lib/osgi/ directory contains the hibernate-osgi jar and all of its dependencies (beyond those in lib/required/ and lib/jpa/)

    +
  • +
  • +

    The lib/jpa-metamodel-generator/ directory contains the jar needed for generating the Criteria API type-safe Metamodel.

    +
  • +
  • +

    The lib/optional/ directory contains the jars needed for the various connection pooling and second-level cache integrations +provided by Hibernate, along with their dependencies.

    +
  • +
+
+
+
+

1.3. Maven Repository Artifacts

+
+

The authoritative repository for Hibernate artifacts is the JBoss Maven repository. The Hibernate artifacts are +synced to Maven Central as part of an automated job (some small delay may occur).

+
+
+

The team responsible for the JBoss Maven repository maintains a number of Wiki pages that contain important information:

+
+
+ +
+
+

The Hibernate ORM artifacts are published under the org.hibernate groupId.

+
+
+
+
+
+

2. Tutorial Using Native Hibernate APIs and hbm.xml Mapping

+
+
+ + + + + +
+ + +This tutorial is located within the download bundle under basic/. +
+
+
+
Objectives
+
    +
  • +

    Bootstrap a Hibernate SessionFactory

    +
  • +
  • +

    Use Hibernate mapping (hbm.xml) files to provide mapping information

    +
  • +
  • +

    Use the Hibernate native APIs

    +
  • +
+
+
+

2.1. The Hibernate configuration file

+
+

For this tutorial, the hibernate.cfg.xml file defines the Hibernate configuration information.

+
+
+

The connection.driver_class, connection.url, connection.username and connection.password <property/> elements +define JDBC connection information. These tutorials utilize the H2 in-memory database, so the values of these properties +are all specific to running H2 in its in-memory mode. connection.pool_size is used to configure the number of +connections in Hibernate’s built-in connection pool.

+
+
+ + + + + +
+ + +The built-in Hibernate connection pool is in no way intended for production use. It lacks several +features found on production-ready connection pools. +
+
+
+

The dialect property specifies the particular SQL variant with which Hibernate will converse.

+
+
+ + + + + +
+ + +In most cases, Hibernate is able to properly determine which dialect to use. This is particularly useful +if your application targets multiple databases. +
+
+
+

The hbm2ddl.auto property enables automatic generation of database schemas directly into the database.

+
+
+

Finally, add the mapping file(s) for persistent classes to the configuration. The resource attribute of the +<mapping/> element causes Hibernate to attempt to locate that mapping as a classpath resource using a +java.lang.ClassLoader lookup.

+
+
+

There are many ways and options to bootstrap a Hibernate SessionFactory. For additional details, see +the Native Bootstrapping topical guide.

+
+
+
+

2.2. The entity Java class

+
+

The entity class for this tutorial is org.hibernate.tutorial.hbm.Event

+
+
+
Notes About the Entity
+
    +
  • +

    This class uses standard JavaBean naming conventions for property getter and setter methods, as well as +private visibility for the fields. Although this is the recommended design, it is not required.

    +
  • +
  • +

    The no-argument constructor, which is also a JavaBean convention, is a requirement for all persistent classes. +Hibernate needs to create objects for you, using Java Reflection. The constructor can be private. However, package +or public visibility is required for runtime proxy generation and efficient data retrieval without bytecode +instrumentation.

    +
  • +
+
+
+
+

2.3. The mapping file

+
+

The mapping file for this tutorial is the classpath resource org/hibernate/tutorial/hbm/Event.hbm.xml (as discussed above).

+
+
+

Hibernate uses the mapping metadata to determine how to load and store objects of the persistent class. The Hibernate +mapping file is one choice for providing Hibernate with this metadata.

+
+
+
Example 1. The class mapping element
+
+
+
+
<class name="Event" table="EVENTS">
+	...
+</class>
+
+
+
+
+
+
Functions of the <varname>class</varname> mapping element
+
    +
  • +

    The name attribute (combined here with the package attribute from the containing <hibernate-mapping/> element) +names the FQN of the class to be defined as an entity.

    +
  • +
  • +

    The table attribute names the database table which contains the data for this entity.

    +
  • +
+
+
+

Instances of the Event class are now mapped to rows in the EVENTS database table.

+
+
+
Example 2. The id mapping element
+
+
+
+
<id name="id" column="EVENT_ID">
+    ...
+</id>
+
+
+
+
+
+

Hibernate uses the property named by the <id/> element to uniquely identify rows in the table.

+
+
+ + + + + +
+ + +It is not required for the id element to map to the table’s actual primary key column(s), but it is +the normal convention. Tables mapped in Hibernate do not even need to define primary keys. However, it is strongly +recommend that all schemas define proper referential integrity. Therefore id and primary key are used interchangeably +throughout Hibernate documentation. +
+
+
+

The <id/> element here names the EVENT_ID column as the primary key of the EVENTS table. It also identifies the +id property of the Event class as the property containing the identifier value.

+
+
+

The generator element informs Hibernate about which strategy is used to generated primary key values for this entity. +This example uses a simple incrementing count.

+
+
+
Example 3. The property mapping element
+
+
+
+
<property name="date" type="timestamp" column="EVENT_DATE"/>
+<property name="title"/>
+
+
+
+
+
+

The two <property/> elements declare the remaining two persistent properties of the Event class: date and title. +The date property mapping includes the column attribute, but the title does not. +In the absence of a column attribute, Hibernate uses the property name as the column name. +This is appropriate for title, but since date is a reserved keyword in most databases, you need to specify a +non-reserved word for the column name.

+
+
+

The title mapping also lacks a type attribute. The types declared and used in the mapping files are neither Java data +types nor SQL database types. Instead, they are Hibernate mapping types, which are converters which translate between +Java and SQL data types. Hibernate attempts to determine the correct conversion and mapping type autonomously if the +type attribute is not specified in the mapping, by using Java reflection to determine the Java type of the declared +property and using a default mapping type for that Java type.

+
+
+

In some cases this automatic detection might not chose the default you expect or need, as seen with the +date property. Hibernate cannot know if the property, which is of type java.util.Date, should map to a SQL +DATE, TIME, or TIMESTAMP datatype. Full date and time information is preserved by mapping the property to +the timestamp converter, which identifies the converter class org.hibernate.type.TimestampType.

+
+
+ + + + + +
+ + +Hibernate determines the mapping type using reflection when the mapping files are processed. This process adds +overhead in terms of time and resources. If startup performance is important, consider explicitly defining the type +to use. +
+
+
+
+

2.4. Example code

+
+

The org.hibernate.tutorial.hbm.NativeApiIllustrationTest class illustrates using the Hibernate native API.

+
+
+ + + + + +
+ + +The examples in these tutorials are presented as JUnit tests, for ease of use. One benefit of this +approach is that setUp and tearDown roughly illustrate how a org.hibernate.SessionFactory is created at the +start-up of an application and closed at the end of the application lifecycle. +
+
+
+
Example 4. Obtaining the org.hibernate.SessionFactory
+
+
+
+
protected void setUp() throws Exception {
+	// A SessionFactory is set up once for an application!
+	final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
+			.configure() // configures settings from hibernate.cfg.xml
+			.build();
+	try {
+		sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
+	}
+	catch (Exception e) {
+		// The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory
+		// so destroy it manually.
+		StandardServiceRegistryBuilder.destroy( registry );
+	}
+}
+
+
+
+
+
+

The setUp method first builds a org.hibernate.boot.registry.StandardServiceRegistry instance which incorporates +configuration information into a working set of Services for use by the SessionFactory. In this tutorial +we defined all configuration information in hibernate.cfg.xml so there is not much interesting to see here.

+
+
+

Using the StandardServiceRegistry we create the org.hibernate.boot.MetadataSources which is the start point for +telling Hibernate about your domain model. Again, since we defined that in hibernate.cfg.xml so there is not much +interesting to see here.

+
+
+

org.hibernate.boot.Metadata represents the complete, partially validated view of the application domain model which the +SessionFactory will be based on.

+
+
+

The final step in the bootstrap process is to build the SessionFactory. The SessionFactory is a +thread-safe object that is instantiated once to serve the entire application.

+
+
+

The SessionFactory acts as a factory for org.hibernate.Session instances, which should be thought of +as a corollary to a "unit of work".

+
+
+
Example 5. Saving entities
+
+
+
+
Session session = sessionFactory.openSession();
+session.beginTransaction();
+session.save( new Event( "Our very first event!", new Date() ) );
+session.save( new Event( "A follow up event", new Date() ) );
+session.getTransaction().commit();
+session.close();
+
+
+
+
+
+

testBasicUsage() first creates some new Event objects and hands them over to Hibernate for management, using the +save() method. Hibernate now takes responsibility to perform an INSERT on the database for each Event.

+
+
+
Example 6. Obtaining a list of entities
+
+
+
+
session = sessionFactory.openSession();
+session.beginTransaction();
+List result = session.createQuery( "from Event" ).list();
+for ( Event event : (List<Event>) result ) {
+    System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );
+}
+session.getTransaction().commit();
+session.close();
+
+
+
+
+
+

Here we see an example of the Hibernate Query Language (HQL) to load all existing Event objects from the database +by generating the appropriate SELECT SQL, sending it to the database and populating Event objects with the result +set data.

+
+
+
+

2.5. Take it further!

+
+
Practice Exercises
+
    +
  • +

    Reconfigure the examples to connect to your own persistent relational database.

    +
  • +
  • +

    Add an association to the Event entity to model a message thread.

    +
  • +
+
+
+
+
+
+

3. Tutorial Using Native Hibernate APIs and Annotation Mappings

+
+
+ + + + + +
+ + +This tutorial is located within the download bundle under annotations/. +
+
+
+
Objectives
+
    +
  • +

    Bootstrap a Hibernate SessionFactory

    +
  • +
  • +

    Use annotations to provide mapping information

    +
  • +
  • +

    Use the Hibernate native APIs

    +
  • +
+
+
+

3.1. The Hibernate configuration file

+
+

The contents are identical to The Hibernate configuration file with one important difference…​ +The <mapping/> element at the very end naming the annotated entity class using the class attribute.

+
+
+
+

3.2. The annotated entity Java class

+
+

The entity class in this tutorial is org.hibernate.tutorial.annotations.Event which follows JavaBean conventions. +In fact the class itself is identical to the one in The entity Java class, except that annotations +are used to provide the metadata, rather than a separate mapping file.

+
+
+
Example 7. Identifying the class as an entity
+
+
+
+
@Entity
+@Table( name = "EVENTS" )
+public class Event {
+    ...
+}
+
+
+
+
+
+

The @javax.persistence.Entity annotation is used to mark a class as an entity. It functions the same as the +<class/> mapping element discussed in The mapping file. Additionally the +@javax.persistence.Table annotation explicitly specifies the table name. Without this specification, the default +table name would be EVENT.

+
+
+
Example 8. Identifying the identifier property
+
+
+
+
@Id
+@GeneratedValue(generator="increment")
+@GenericGenerator(name="increment", strategy = "increment")
+public Long getId() {
+    return id;
+}
+
+
+
+
+
+

@javax.persistence.Id marks the property which defines the entity’s identifier.

+
+
+

@javax.persistence.GeneratedValue and @org.hibernate.annotations.GenericGenerator work in tandem +to indicate that Hibernate should use Hibernate’s increment generation strategy for this entity’s identifier values.

+
+
+
Example 9. Identifying basic properties
+
+
+
+
public String getTitle() {
+    return title;
+}
+
+@Temporal(TemporalType.TIMESTAMP)
+@Column(name = "EVENT_DATE")
+public Date getDate() {
+    return date;
+}
+
+
+
+
+
+

As in The mapping file, the date property needs special handling to account for its special +naming and its SQL type.

+
+
+

Attributes of an entity are considered persistent by default when mapping with annotations, which is why we don’t see +any mapping information associated with title.

+
+
+
+

3.3. Example code

+
+

org.hibernate.tutorial.annotations.AnnotationsIllustrationTest is essentially the same as +org.hibernate.tutorial.hbm.NativeApiIllustrationTest discussed in Example code.

+
+
+
+

3.4. Take it further!

+
+
Practice Exercises
+
    +
  • +

    Add an association to the Event entity to model a message thread. Use the +User Guide for more details.

    +
  • +
  • +

    Add a callback to receive notifications when an Event is created, updated or deleted. +Try the same with an event listener. Use the +User Guide for more details.

    +
  • +
+
+
+
+
+
+

4. Tutorial Using the Java Persistence API (JPA)

+
+
+ + + + + +
+ + +This tutorial is located within the download bundle under entitymanager/. +
+
+
+
Objectives
+
    +
  • +

    Bootstrap a JPA EntityManagerFactory

    +
  • +
  • +

    Use annotations to provide mapping information

    +
  • +
  • +

    Use JPA API calls

    +
  • +
+
+
+

4.1. persistence.xml

+
+

The previous tutorials used the Hibernate-specific hibernate.cfg.xml configuration file. JPA, however, defines +a different bootstrap process that uses its own configuration file named persistence.xml. This bootstrapping process +is defined by the JPA specification. In Java™ SE environments the persistence provider (Hibernate in this case) +is required to locate all JPA configuration files by classpath lookup of the META-INF/persistence.xml resource name.

+
+
+
Example 10. persistence.xml
+
+
+
+
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+        version="2.0">
+    <persistence-unit name="org.hibernate.tutorial.jpa">
+        ...
+    </persistence-unit>
+</persistence>
+
+
+
+
+
+

persistence.xml files should provide a unique name for each "persistence unit". Applications use this name to +reference the configuration when obtaining an javax.persistence.EntityManagerFactory reference.

+
+
+

The settings defined in the <properties/> element are discussed in The Hibernate configuration file. +Here the javax.persistence-prefixed varieties are used when possible. Notice that the remaining +Hibernate-specific configuration setting names are now prefixed with hibernate..

+
+
+

Additionally, the <class/> element functions the same as we saw in The Hibernate configuration file.

+
+
+
+

4.2. The annotated entity Java class

+
+

The entity is exactly the same as in The annotated entity Java class.

+
+
+
+

4.3. Example code

+
+

The previous tutorials used the Hibernate native APIs. This tutorial uses the JPA APIs.

+
+
+
Example 11. Obtaining the javax.persistence.EntityManagerFactory
+
+
+
+
protected void setUp() throws Exception {
+	sessionFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.jpa" );
+}
+
+
+
+
+
+

Notice again that the persistence unit name is org.hibernate.tutorial.jpa, which matches persistence.xml.

+
+
+
Example 12. Saving (persisting) entities
+
+
+
+
EntityManager entityManager = sessionFactory.createEntityManager();
+entityManager.getTransaction().begin();
+entityManager.persist( new Event( "Our very first event!", new Date() ) );
+entityManager.persist( new Event( "A follow up event", new Date() ) );
+entityManager.getTransaction().commit();
+entityManager.close();
+
+
+
+
+
+

The code is similar to Saving entities. The javax.persistence.EntityManager interface +is used instead of the org.hibernate.Session interface. JPA calls this operation "persist" instead of "save".

+
+
+
Example 13. Obtaining a list of entities
+
+
+
+
entityManager = sessionFactory.createEntityManager();
+entityManager.getTransaction().begin();
+List<Event> result = entityManager.createQuery( "from Event", Event.class ).getResultList();
+for ( Event event : result ) {
+	System.out.println( "Event (" + event.getDate() + ") : " + event.getTitle() );
+}
+entityManager.getTransaction().commit();
+entityManager.close();
+
+
+
+
+
+

Again, the code is pretty similar to what we saw in Obtaining a list of entities.

+
+
+
+

4.4. Take it further!

+
+
Practice Exercises
+
    +
  • +

    Develop an EJB Session bean to investigate implications of using a container-managed +persistence context. Try both stateless and stateful use-cases.

    +
  • +
  • +

    Use listeners with CDI-based injection to develop a JMS-based event message hub

    +
  • +
+
+
+
+
+
+

5. Tutorial Using Envers

+
+
+ + + + + +
+ + +This tutorial is located within the download bundle under envers/. +
+
+
+
Objectives
+
    +
  • +

    Annotate an entity as historical

    +
  • +
  • +

    Configure Envers

    +
  • +
  • +

    Use the Envers APIs to view and analyze historical data

    +
  • +
+
+
+

5.1. persistence.xml

+
+

This file was discussed in the JPA tutorial in persistence.xml, and is essentially the same here.

+
+
+
+

5.2. The annotated entity Java class

+
+

Again, the entity is largely the same as in The annotated entity Java class. The major difference is the +addition of the @org.hibernate.envers.Audited annotation, which tells Envers to automatically track changes to this +entity.

+
+
+
+

5.3. Example code

+
+

The code saves some entities, makes a change to one of the entities and then uses the Envers API to pull back the +initial revision as well as the updated revision. A revision refers to a historical snapshot of an entity.

+
+
+
Example 14. Using the org.hibernate.envers.AuditReader
+
+
+
+
public void testBasicUsage() {
+    ...
+    AuditReader reader = AuditReaderFactory.get( entityManager );
+    Event firstRevision = reader.find( Event.class, 2L, 1 );
+    ...
+    Event secondRevision = reader.find( Event.class, 2L, 2 );
+    ...
+}
+
+
+
+
+
+

We see that an org.hibernate.envers.AuditReader is obtained from the org.hibernate.envers.AuditReaderFactory +which wraps the javax.persistence.EntityManager.

+
+
+

Next, the find method retrieves specific revisions of the entity. The first call says to find revision number +1 of Event with id 2. The second call says to find revision number 2 of Event with id 2.

+
+
+
+

5.4. Take it further!

+
+
Practice Exercises
+
    +
  • +

    Provide a custom revision entity to additionally capture who made the changes.

    +
  • +
  • +

    Write a query to retrieve only historical data which meets some criteria. Use the User Guide to see how +Envers queries are constructed.

    +
  • +
  • +

    Experiment with auditing entities which have various forms of relationships (many-to-one, many-to-many, etc). Try +retrieving historical versions (revisions) of such entities and navigating the object tree.

    +
  • +
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 7ec00d2..3dd3526 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -7,5 +7,8 @@ Hello, Servlets! + + + \ No newline at end of file diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 47a68a3..9498fec 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -1,30 +1,238 @@ - - - - - - Document - - + -

Maxwell’s Magnificent Minecraft Modpack Maker

-


-

User Story

-



- As a user without an account I can ...

- - See all the available mods
- Filter mods by who created them
- Register an account
-


-

As a user with an account I can ...

- Log in as a user
- Update a mod I own
- Create a mod that doesn't already exist
- Create a modpack
- Add mods to the modpack
- -

+ +
+ +
+ + - \ No newline at end of file + + +
+
+

PitoA1000Places

+

Pizzeria

+ +
+ + + + + + + + + + + + + + + Simple HTML HomePage + +