• Spring In Action 5 学习笔记 chapter4 Spring Security部分关键点


    关键点

    问题:原书中创建的User对象在H2 database中为关键词,导致h2 database报错类似【org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "drop table if exists [*]user CASCADE "; expected "identifier"; SQL statement: drop table if exists user CASCADE [42001-214]】

    规避办法:不能使用user关键词作为H2 database表名,本人采用tuser作为表名及类名绕过了此bug。


    问题:报错【role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_USER' at org.springframework.security.config.annotation】

    原因及解决办法:原因上面错误已指出,不应该以ROLE_开头,解决办法:

    需要将代码

    1. @Override
    2. protected void configure(HttpSecurity http) throws Exception {
    3. http
    4. .authorizeRequests()
    5. .antMatchers("/design", "/orders")
    6. .hasRole("ROLE_USER") //导致bug的代码
    7. .antMatchers(“/”, "/**").permitAll();
    8. }

    改为如下

    1. @Override
    2. protected void configure(HttpSecurity http) throws Exception {
    3. http
    4. .authorizeRequests()
    5. .antMatchers("/design", "/orders")
    6. .access("hasRole('ROLE_USER')") //修正后的代码
    7. .antMatchers(“/”, "/**").access("permitAll");
    8. }

     


    问题:userRepository中的 findByUsername()总是返回空,导致DesignTacoController.java的showDesignForm方法中报错java.lang.NullPointerException: null 

    解决办法

    1.检查user.java中是否自动生成代码时设置username为空了,为空则去掉

    2.对JPA 的指定方法进行自定义SQL查询,代码如下

    1. public interface TuserRepository extends CrudRepository<Tuser,Long> {
    2. @Query(value = "SELECT id, username,password FROM TUSER where username=?1",nativeQuery = true)
    3. Tuser findByUsername(String username);
    4. }

    问题:/design页面提交时总报错

    原因及解决办法:design页面中有两个form表单,需要为每个表单添加action标记,以便每个表单提交后知道具体转向哪个url对应的controller。具体如下:

     
    

    问题:登录后访问/design出现浏览器提示403 Forbidden错误

    原因及解决办法:原因为CSRF机制,需要在design.html页面中增加csrf的标记  使Thymeleaf自动将token传递给spring security。

    至于网上大部分解决方法写的禁用CSRF方法不可取,原书作者也一再强调了。


    问题:加了Spring Security后启动程序后无法访问H2database的页面查询数据

    原因及解决办法:原因为spring security也对H2 Database的页面进行了保护导致H2 database的页面无法访问。解决办法是在SecurityConfig.java的

    protected void configure(HttpSecurity http)

    函数中增加如下代码

    1. http
    2. .antMatchers("/h2-console/**").permitAll() // 放行 H2 的请求
    3. .and().csrf().ignoringAntMatchers("/h2-console/**") // 禁用 H2 控制台的 CSRF 防护

    问题:调试时如何查看jpa生成的sql?

    解决:在application.properties中增加以下配置

    spring.jpa.show-sql=true
    spring.jpa.properties.hibernate.format_sql=true
    


    目录

    关键点

    部分源码文件

    IDEA中代码文件目录

    配置相关

    pom.xml

    application.propertites

    TacocloudApplication.java

    Security层

    SecurityConfig.java

    UserRepositoryUserDetailsService.java

    RegistrationForm.java

    RegistrationController.java

    Model层

    Ingredient.java

    Order.java

    Taco.java

    Tuser.java

    data层

    IngredientRepository.java

    OrderRepository.java

    TacoRepository.java

    TuserRepository.java

    Controller层

    DesignTacoController.java

    HomeController.java

    WebConfig.java

    OrderController.java

    IngredientByIdConverter.java

    前端 templates

    registration.html

    home.html

    login.html

    design.html

    orderForm.html

    部分sql

    schema.sql

    data.sql

    启动运行

    IDEA启动程序后的日志



    部分源码文件

    IDEA中代码文件目录

     

     

    配置相关

    pom.xml

    安全相关的关键依赖是spring-boot-starter-security

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <groupId>com.wdh</groupId>
    6. <artifactId>tacocloud</artifactId>
    7. <version>0.0.1-SNAPSHOT</version>
    8. <name>tacocloud</name>
    9. <description>Demo project for Spring Boot</description>
    10. <properties>
    11. <java.version>1.8</java.version>
    12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    13. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    14. <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    15. </properties>
    16. <dependencies>
    17. <dependency>
    18. <groupId>org.springframework.boot</groupId>
    19. <artifactId>spring-boot-starter-thymeleaf</artifactId>
    20. </dependency>
    21. <dependency>
    22. <groupId>org.springframework.boot</groupId>
    23. <artifactId>spring-boot-starter-web</artifactId>
    24. </dependency>
    25. <dependency>
    26. <groupId>org.springframework.boot</groupId>
    27. <artifactId>spring-boot-devtools</artifactId>
    28. <scope>runtime</scope>
    29. <optional>true</optional>
    30. </dependency>
    31. <dependency>
    32. <groupId>org.projectlombok</groupId>
    33. <artifactId>lombok</artifactId>
    34. <optional>true</optional>
    35. </dependency>
    36. <dependency>
    37. <groupId>org.springframework.boot</groupId>
    38. <artifactId>spring-boot-starter-test</artifactId>
    39. <scope>test</scope>
    40. <exclusions>
    41. <exclusion>
    42. <groupId>org.junit.vintage</groupId>
    43. <artifactId>junit-vintage-engine</artifactId>
    44. </exclusion>
    45. </exclusions>
    46. </dependency>
    47. <dependency>
    48. <groupId>org.projectlombok</groupId>
    49. <artifactId>lombok</artifactId>
    50. <version>1.18.24</version>
    51. <scope>provided</scope>
    52. </dependency>
    53. <dependency>
    54. <groupId>org.springframework.boot</groupId>
    55. <artifactId>spring-boot-starter-validation</artifactId>
    56. <!-- <version>2.3.7.RELEASE</version> 根据自己的版本引入-->
    57. </dependency>
    58. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
    59. <dependency>
    60. <groupId>org.springframework.boot</groupId>
    61. <artifactId>spring-boot-starter-data-jpa</artifactId>
    62. <!--<version>2.7.3</version>-->
    63. </dependency>
    64. <!-- https://mvnrepository.com/artifact/org.eclipse.persistence/eclipselink -->
    65. <dependency>
    66. <groupId>org.eclipse.persistence</groupId>
    67. <artifactId>eclipselink</artifactId>
    68. <version>4.0.0-M3</version>
    69. </dependency>
    70. <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
    71. <dependency>
    72. <groupId>com.h2database</groupId>
    73. <artifactId>h2</artifactId>
    74. <version>2.1.214</version>
    75. <scope>runtime</scope>
    76. </dependency>
    77. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
    78. <dependency>
    79. <groupId>org.springframework.boot</groupId>
    80. <artifactId>spring-boot-starter-security</artifactId>
    81. <version>2.7.3</version>
    82. </dependency>
    83. </dependencies>
    84. <dependencyManagement>
    85. <dependencies>
    86. <dependency>
    87. <groupId>org.springframework.boot</groupId>
    88. <artifactId>spring-boot-dependencies</artifactId>
    89. <version>${spring-boot.version}</version>
    90. <type>pom</type>
    91. <scope>import</scope>
    92. </dependency>
    93. </dependencies>
    94. </dependencyManagement>
    95. <build>
    96. <plugins>
    97. <plugin>
    98. <groupId>org.apache.maven.plugins</groupId>
    99. <artifactId>maven-compiler-plugin</artifactId>
    100. <version>3.8.1</version>
    101. <configuration>
    102. <source>1.8</source>
    103. <target>1.8</target>
    104. <encoding>UTF-8</encoding>
    105. </configuration>
    106. </plugin>
    107. <plugin>
    108. <groupId>org.springframework.boot</groupId>
    109. <artifactId>spring-boot-maven-plugin</artifactId>
    110. <version>2.3.7.RELEASE</version>
    111. <configuration>
    112. <mainClass>com.wdh.tacocloud.TacocloudApplication</mainClass>
    113. </configuration>
    114. <executions>
    115. <execution>
    116. <id>repackage</id>
    117. <goals>
    118. <goal>repackage</goal>
    119. </goals>
    120. </execution>
    121. </executions>
    122. </plugin>
    123. </plugins>
    124. </build>
    125. </project>

    application.propertites

    1. # 应用名称
    2. spring.application.name=tacocloud
    3. # 应用服务 WEB 访问端口
    4. server.port=8080
    5. # THYMELEAF (ThymeleafAutoConfiguration)
    6. # 开启模板缓存(默认值: true ) wdh:正式上线时设置为true,开发调试时设置为false便于刷新页面获取最新目标
    7. spring.thymeleaf.cache=false
    8. # 检查模板是否存在,然后再呈现
    9. spring.thymeleaf.check-template=true
    10. # 检查模板位置是否正确(默认值 :true
    11. spring.thymeleaf.check-template-location=true
    12. #Content-Type 的值(默认值: text/html )
    13. spring.thymeleaf.content-type=text/html
    14. # 开启 MVC Thymeleaf 视图解析(默认值: true
    15. spring.thymeleaf.enabled=true
    16. # 模板编码
    17. spring.thymeleaf.encoding=UTF-8
    18. # 要被排除在解析之外的视图名称列表,⽤逗号分隔
    19. spring.thymeleaf.excluded-view-names=
    20. # 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
    21. spring.thymeleaf.mode=HTML5
    22. # 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/
    23. spring.thymeleaf.prefix=classpath:/templates/
    24. # 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
    25. spring.thymeleaf.suffix=.html
    26. spring.jpa.show-sql=true
    27. spring.jpa.properties.hibernate.format_sql=true

    TacocloudApplication.java

    1. package com.wdh.tacocloud;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. @SpringBootApplication
    5. public class TacocloudApplication {
    6. //注意,使用spring data Jdbc时 会自动执行data.sql和schema.sql
    7. //注意,使用spring data JPA时 不会自动执行data.sql,仅会执行schema.sql
    8. //可以打开http://localhost:8080/h2-console,根据idea 控制台打印的H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:27598f8c-e777-4993-83df-7076ce35376b'信息登录进行手动录入数据
    9. //参考https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization.using-jpa
    10. public static void main(String[] args) {
    11. SpringApplication.run(TacocloudApplication.class, args);
    12. }
    13. }

    Security层

    SecurityConfig.java

    1. package com.wdh.tacocloud.security;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    7. import org.springframework.security.config.annotation.web.builders.WebSecurity;
    8. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    9. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    10. import org.springframework.security.core.userdetails.UserDetailsService;
    11. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    12. import org.springframework.security.crypto.password.PasswordEncoder;
    13. import org.springframework.security.crypto.password.StandardPasswordEncoder;
    14. import javax.sql.DataSource;
    15. /**
    16. * @author WangDH
    17. * @create 2022-09-02 17:10
    18. */
    19. @Configuration
    20. @EnableWebSecurity
    21. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    22. @Autowired
    23. private UserDetailsService userDetailsService;
    24. @Bean
    25. public PasswordEncoder encoder(){
    26. PasswordEncoder encoder=new StandardPasswordEncoder("53cr3t");
    27. return encoder;
    28. }
    29. @Override
    30. public void configure(AuthenticationManagerBuilder auth) throws Exception {
    31. //自定义用户身份验证
    32. auth
    33. .userDetailsService(userDetailsService)
    34. .passwordEncoder(encoder());
    35. }
    36. @Override
    37. protected void configure(HttpSecurity http) throws Exception {
    38. //super.configure(http);
    39. //配置为对以下路径需要认证方可访问:/design /orders
    40. //配置为对其他路径不需要认证
    41. //上述认证配置的代码顺序很重要
    42. //配置为使用自定义登录页面
    43. //登出页面设置为根目录
    44. //.hasRole("ROLE_USER") //此代码会报错,Caused by: java.lang.IllegalArgumentException: role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_USER'
    45. http
    46. .authorizeRequests()
    47. .antMatchers("/design","/orders")
    48. .access("hasRole('ROLE_USER')")//.hasRole("USER")
    49. .antMatchers("/","/**")
    50. .permitAll()
    51. .antMatchers("/h2-console/**").permitAll() // 放行 H2 的请求
    52. .and().csrf().ignoringAntMatchers("/h2-console/**") // 禁用 H2 控制台的 CSRF 防护
    53. .and().headers().frameOptions().sameOrigin() // 允许来自同一来源的 H2 控制台的请求
    54. .and()
    55. .formLogin()
    56. .loginPage("/login")
    57. .defaultSuccessUrl("/design")
    58. .and()
    59. .logout()
    60. .logoutSuccessUrl("/");
    61. }
    62. }

    UserRepositoryUserDetailsService.java

    1. package com.wdh.tacocloud.security;
    2. import com.wdh.tacocloud.data.TuserRepository;
    3. import com.wdh.tacocloud.model.Tuser;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.security.core.userdetails.UserDetails;
    6. import org.springframework.security.core.userdetails.UserDetailsService;
    7. import org.springframework.security.core.userdetails.UsernameNotFoundException;
    8. import org.springframework.stereotype.Service;
    9. /**
    10. * @author WangDH
    11. * @create 2022-09-05 17:56
    12. */
    13. @Service
    14. public class UserRepositoryUserDetailsService implements UserDetailsService {
    15. private TuserRepository userRepo;
    16. @Autowired
    17. public UserRepositoryUserDetailsService(TuserRepository userRepository) {
    18. this.userRepo=userRepository;
    19. }
    20. @Override
    21. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    22. //return null;
    23. Tuser user=userRepo.findByUsername(username);
    24. if(user!=null){
    25. return user;
    26. }
    27. throw new UsernameNotFoundException("user["+username+"] not found.");
    28. }
    29. }

    RegistrationForm.java

    1. package com.wdh.tacocloud.security;
    2. import com.wdh.tacocloud.model.Tuser;
    3. import lombok.Data;
    4. import org.springframework.security.crypto.password.PasswordEncoder;
    5. /**
    6. * @author WangDH
    7. * @create 2022-09-06 9:57
    8. */
    9. @Data
    10. public class RegistrationForm {
    11. private String username;
    12. private String password;
    13. public Tuser toUser(PasswordEncoder passwordEncoder){
    14. return new Tuser(username,passwordEncoder.encode(password));
    15. }
    16. }

    RegistrationController.java

    1. package com.wdh.tacocloud.security;
    2. import com.wdh.tacocloud.data.TuserRepository;
    3. import com.wdh.tacocloud.security.RegistrationForm;
    4. import org.springframework.security.crypto.password.PasswordEncoder;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.web.bind.annotation.GetMapping;
    7. import org.springframework.web.bind.annotation.PostMapping;
    8. import org.springframework.web.bind.annotation.RequestMapping;
    9. /**
    10. * @author WangDH
    11. * @create 2022-09-06 9:48
    12. */
    13. @Controller
    14. @RequestMapping("/register")
    15. public class RegistrationController {
    16. private TuserRepository userRepo;
    17. private PasswordEncoder passwordEncoder;
    18. public RegistrationController(TuserRepository userRepo, PasswordEncoder passwordEncoder) {
    19. this.userRepo = userRepo;
    20. this.passwordEncoder = passwordEncoder;
    21. }
    22. @GetMapping
    23. public String registerForm(){
    24. return "registration";
    25. }
    26. @PostMapping
    27. public String processRegistration(RegistrationForm form){
    28. userRepo.save(form.toUser(passwordEncoder));
    29. return "redirect:/login";
    30. }
    31. }

    Model层

    Ingredient.java

    1. package com.wdh.tacocloud.model;
    2. import lombok.AccessLevel;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. import lombok.RequiredArgsConstructor;
    6. import javax.persistence.Entity;
    7. import javax.persistence.Id;
    8. /**
    9. * @author WangDH
    10. * @create 2022-08-24 17:18
    11. */
    12. @Data
    13. @RequiredArgsConstructor
    14. @NoArgsConstructor(access = AccessLevel.PRIVATE,force = true) //因JPA需要一个无参构造函数,这里通过注解让lombok生成构造函数
    15. @Entity //JPA需要的注解
    16. public class Ingredient {
    17. @Id //jpa需要的注解,表明该字段为主键
    18. private final String id;
    19. private final String name;
    20. private final String mytype;
    21. public static enum Type{
    22. WRAP,PROTEIN,VEGGIES,CHEESE,SAUCE
    23. }
    24. }

    Order.java

    1. package com.wdh.tacocloud.model;
    2. import lombok.Data;
    3. import javax.persistence.*;
    4. import javax.validation.constraints.Digits;
    5. import javax.validation.constraints.NotBlank;
    6. import javax.validation.constraints.Pattern;
    7. import org.hibernate.validator.constraints.CreditCardNumber;
    8. import java.io.Serializable;
    9. import java.util.ArrayList;
    10. import java.util.Date;
    11. import java.util.List;
    12. /**
    13. * @author WangDH
    14. * @create 2022-08-25 10:10
    15. */
    16. @Data
    17. @Entity
    18. @Table(name="Taco_Order")
    19. public class Order implements Serializable {
    20. @Id
    21. @GeneratedValue(strategy = GenerationType.AUTO)
    22. private Long id;
    23. private Date placedAt;
    24. @NotBlank(message="Delivery name is required")
    25. private String deliveryName;
    26. @NotBlank(message="Street is required")
    27. private String deliveryStreet;
    28. @NotBlank(message="City is required")
    29. private String deliveryCity;
    30. @NotBlank(message="State is required")
    31. private String deliveryState;
    32. @NotBlank(message="Zip code is required")
    33. private String deliveryZip;
    34. @CreditCardNumber(message = "Not a valid credit card number")
    35. private String ccNumber; //Test VISA credit card number: 4005550000000019
    36. @Pattern(regexp = "^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$",message = "Must be formatted MM/YY")
    37. private String ccExpiration;
    38. @Digits(integer = 3,fraction = 0,message = "Invalid CVV")
    39. private String ccCVV;
    40. @ManyToMany(targetEntity = Taco.class)
    41. private List tacos=new ArrayList<>();
    42. public void addDesign(Taco design){
    43. this.tacos.add(design);
    44. }
    45. @PrePersist
    46. void placedAt(){
    47. this.placedAt=new Date();
    48. }
    49. @ManyToOne
    50. private Tuser user;
    51. }

    Taco.java

    1. package com.wdh.tacocloud.model;
    2. import lombok.Data;
    3. import javax.persistence.*;
    4. import javax.validation.constraints.NotNull;
    5. import javax.validation.constraints.Size;
    6. import java.util.Date;
    7. import java.util.List;
    8. /**
    9. * @author WangDH
    10. * @create 2022-08-25 9:12
    11. */
    12. @Data
    13. @Entity
    14. public class Taco {
    15. @Id
    16. @GeneratedValue(strategy = GenerationType.AUTO)
    17. private Long id;
    18. private Date createdAt;
    19. @NotNull
    20. @Size(min = 5,message = "Name must be at least 5 characters long")
    21. private String name;
    22. @ManyToMany(targetEntity = Ingredient.class)
    23. @Size(min = 1,message = "You must choose at least 1 ingredient.")
    24. private List ingredients;
    25. @PrePersist
    26. void createdAt(){
    27. this.createdAt=new Date();
    28. }
    29. }

    Tuser.java

    1. package com.wdh.tacocloud.model;
    2. import lombok.AccessLevel;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. import lombok.RequiredArgsConstructor;
    6. import org.springframework.security.core.GrantedAuthority;
    7. import org.springframework.security.core.authority.SimpleGrantedAuthority;
    8. import org.springframework.security.core.userdetails.UserDetails;
    9. import javax.persistence.Entity;
    10. import javax.persistence.GeneratedValue;
    11. import javax.persistence.GenerationType;
    12. import javax.persistence.Id;
    13. import java.util.Arrays;
    14. import java.util.Collection;
    15. /**
    16. * @author WangDH
    17. * @create 2022-09-05 17:42
    18. */
    19. @Entity
    20. @Data
    21. @NoArgsConstructor(access = AccessLevel.PRIVATE,force=true)
    22. @RequiredArgsConstructor
    23. public class Tuser implements UserDetails {
    24. //UserDetails是Spring内部接口,org.springframework.security.core.userdetails
    25. //由于user是H2Database的关键字,在IDEA中schema.sql中使用user作为表名会导致H2Database建表错误。
    26. @Id
    27. @GeneratedValue(strategy = GenerationType.AUTO)
    28. private Long id;
    29. private final String username;
    30. private final String password;
    31. @Override
    32. public Collectionextends GrantedAuthority> getAuthorities() {
    33. return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
    34. }
    35. @Override
    36. public boolean isAccountNonExpired() {
    37. return true;
    38. }
    39. @Override
    40. public boolean isAccountNonLocked() {
    41. return true;
    42. }
    43. @Override
    44. public boolean isCredentialsNonExpired() {
    45. return true;
    46. }
    47. @Override
    48. public boolean isEnabled() {
    49. return true;
    50. }
    51. }

    data层

    IngredientRepository.java

    1. package com.wdh.tacocloud.data;
    2. import com.wdh.tacocloud.model.Ingredient;
    3. import org.springframework.data.repository.CrudRepository;
    4. /**
    5. * @author WangDH
    6. * @create 2022-08-25 14:43
    7. *
    8. * Ingredient实体的数据访问接口
    9. */
    10. public interface IngredientRepository extends CrudRepository<Ingredient,String> {
    11. //CrudRepository 已经包含增删改查的实现,这里不需要再写常规的实现代码
    12. }

    OrderRepository.java

    1. package com.wdh.tacocloud.data;
    2. import com.wdh.tacocloud.model.Order;
    3. import org.springframework.data.repository.CrudRepository;
    4. import java.util.Date;
    5. import java.util.List;
    6. /**
    7. * @author WangDH
    8. * @create 2022-08-25 17:20
    9. */
    10. public interface OrderRepository extends CrudRepository<Order,Long> {
    11. //CrudRepository 已经包含增删改查的实现,具体可看CrudRepository定义,这里不需要再写实现代码
    12. //以下是自定义JPA repository
    13. List<Order> findByDeliveryZip(String deliveryZip);
    14. List<Order> readOrdersByDeliveryZipAndPlacedAtBetween(
    15. String deliveryZip, Date startdate, Date endDate
    16. );
    17. }

    TacoRepository.java

    1. package com.wdh.tacocloud.data;
    2. import com.wdh.tacocloud.model.Taco;
    3. import org.springframework.data.repository.CrudRepository;
    4. /**
    5. * @author WangDH
    6. * @create 2022-08-25 17:18
    7. */
    8. public interface TacoRepository extends CrudRepository<Taco,Long> {
    9. //CrudRepository 已经包含增删改查的实现,这里不需要再写实现代码
    10. }

    TuserRepository.java

    1. package com.wdh.tacocloud.data;
    2. import com.wdh.tacocloud.model.Tuser;
    3. import org.springframework.data.jpa.repository.Query;
    4. import org.springframework.data.repository.CrudRepository;
    5. /**
    6. * @author WangDH
    7. * @create 2022-09-05 17:52
    8. */
    9. public interface TuserRepository extends CrudRepository<Tuser,Long> {
    10. @Query(value = "SELECT id, username,password FROM TUSER where username=?1",nativeQuery = true)
    11. Tuser findByUsername(String username);
    12. }

    Controller层

    DesignTacoController.java

    1. package com.wdh.tacocloud.controller;
    2. import com.wdh.tacocloud.data.IngredientRepository;
    3. import com.wdh.tacocloud.data.TacoRepository;
    4. import com.wdh.tacocloud.data.TuserRepository;
    5. import com.wdh.tacocloud.model.Ingredient;
    6. import com.wdh.tacocloud.model.Ingredient.Type;
    7. import com.wdh.tacocloud.model.Order;
    8. import com.wdh.tacocloud.model.Taco;
    9. import com.wdh.tacocloud.model.Tuser;
    10. import lombok.extern.slf4j.Slf4j;
    11. import org.springframework.beans.factory.annotation.Autowired;
    12. import org.springframework.stereotype.Controller;
    13. import org.springframework.ui.Model;
    14. import org.springframework.validation.Errors;
    15. import org.springframework.web.bind.annotation.*;
    16. import javax.validation.Valid;
    17. import java.security.Principal;
    18. import java.util.ArrayList;
    19. import java.util.Arrays;
    20. import java.util.List;
    21. import java.util.stream.Collectors;
    22. /**
    23. * @author WangDH
    24. * @create 2022-08-24 17:34
    25. *
    26. * 在控制器中注入并使用repository
    27. */
    28. @Slf4j
    29. @Controller
    30. @RequestMapping("/design")
    31. @SessionAttributes("order")
    32. public class DesignTacoController {
    33. private final IngredientRepository ingredientRepository;
    34. private TacoRepository designRepo;
    35. private TuserRepository tuserRepo;
    36. @Autowired
    37. public DesignTacoController(
    38. IngredientRepository ingredientRepository,
    39. TacoRepository tacoRepository,
    40. TuserRepository tuserRepository
    41. ) {
    42. this.ingredientRepository = ingredientRepository;
    43. this.designRepo=tacoRepository;
    44. this.tuserRepo=tuserRepository;
    45. }
    46. @ModelAttribute(name="taco")
    47. public Taco taco(){
    48. return new Taco();
    49. }
    50. @ModelAttribute(name="order")
    51. public Order order(){
    52. return new Order();
    53. }
    54. @GetMapping
    55. public String showDesignForm(Model model, Principal principal){
    56. List<Ingredient> ingredients=new ArrayList<>();
    57. Iterable<Ingredient> listAll= ingredientRepository.findAll();
    58. listAll.forEach(i->ingredients.add(i));
    59. Type[] types=Ingredient.Type.values();
    60. for(Type type:types){
    61. model.addAttribute(type.toString().toLowerCase(),
    62. filterByType(ingredients,type));
    63. }
    64. String strLoginUsername=principal.getName();//获取登录的用户名
    65. log.info("--showDesignForm--strLoginUsername="+strLoginUsername);
    66. Tuser tuser=tuserRepo.findByUsername(strLoginUsername);
    67. model.addAttribute("user",tuser);//将已登录的用户对象信息传递到前端Thymeleaf
    68. return "design";
    69. }
    70. private List<Ingredient> filterByType(List<Ingredient> ingredients,Type type){
    71. return ingredients.stream().filter(x->x.getMytype().equals(type.toString())).collect(Collectors.toList());
    72. }
    73. //接收提交的信息
    74. //注意:在desgin.html提交信息时如果提示403错误,则需要在design.html页面中增加csrf的标记
    75. // <input type="hidden" name="_csrf" th:value="${_csrf.token}" />
    76. //由于design.html有两个form,所以每个form都要指定th:action,防止出错
    77. @PostMapping
    78. public String processDesign(@Valid Taco design,
    79. Errors errors,
    80. @ModelAttribute Order order){
    81. if(errors.hasErrors())
    82. {
    83. //log.info("processDesign enter,has error.errors="+errors);
    84. log.info("processDesign enter,has error.errors");
    85. return "design";
    86. }
    87. log.info("Process design:"+design);
    88. Taco saved=designRepo.save(design);
    89. order.addDesign(saved);
    90. return "redirect:/orders/current";
    91. }
    92. }

    HomeController.java

    1. package com.wdh.tacocloud.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.GetMapping;
    4. /**
    5. * @author WangDH
    6. * @create 2022-08-24 16:25
    7. */
    8. @Controller
    9. public class HomeController {
    10. @GetMapping("/")
    11. public String home(){
    12. return "home";
    13. }
    14. }

    WebConfig.java

    1. package com.wdh.tacocloud.controller;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    4. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    5. /**
    6. * @author WangDH
    7. * @create 2022-08-25 13:48 *
    8. * 声明视图控制器,浏览器输入http://localhost:8082/myhome后即可直接转向myhome.html页面
    9. */
    10. @Configuration
    11. public class WebConfig implements WebMvcConfigurer {
    12. @Override
    13. public void addViewControllers(ViewControllerRegistry registry) {
    14. registry.addViewController("/myhome").setViewName("myhome");
    15. registry.addViewController("/login");//配置收到/login请求时转向相应页面
    16. }
    17. }

    OrderController.java

    1. package com.wdh.tacocloud.controller;
    2. import com.wdh.tacocloud.data.OrderRepository;
    3. import com.wdh.tacocloud.model.Order;
    4. import com.wdh.tacocloud.model.Tuser;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.springframework.security.core.Authentication;
    7. import org.springframework.security.core.annotation.AuthenticationPrincipal;
    8. import org.springframework.stereotype.Controller;
    9. import org.springframework.ui.Model;
    10. import org.springframework.validation.Errors;
    11. import org.springframework.web.bind.annotation.*;
    12. import org.springframework.web.bind.support.SessionStatus;
    13. import javax.validation.Valid;
    14. import java.security.Principal;
    15. /**
    16. * @author WangDH
    17. * @create 2022-08-25 10:07
    18. */
    19. @Slf4j
    20. @Controller
    21. @RequestMapping("/orders")
    22. @SessionAttributes("order")
    23. public class OrderController {
    24. private OrderRepository orderRepo;
    25. public OrderController(OrderRepository orderRepo){
    26. this.orderRepo=orderRepo;
    27. }
    28. @GetMapping("/current") //与OrderController的url联合组成/orders/current
    29. public String orderForm(@AuthenticationPrincipal Tuser user,
    30. @ModelAttribute Order order){
    31. String strLoginUsername=user.getUsername();
    32. order.setDeliveryName(strLoginUsername);
    33. return "orderForm";
    34. }
    35. @PostMapping
    36. public String processOrder(
    37. @Valid Order order,
    38. Errors errors,
    39. SessionStatus sessionStatus,
    40. Authentication authentication
    41. ){
    42. if(errors.hasErrors()){
    43. //log.info("processOrder tips,has errors="+errors);
    44. log.info("processOrder tips,has errors=");
    45. return "orderForm";
    46. }
    47. Tuser user=(Tuser)authentication.getPrincipal();//获取登录用户
    48. order.setUser(user);
    49. orderRepo.save(order);
    50. sessionStatus.setComplete();//清除session中的缓存
    51. log.info("Order submitted:"+order);
    52. return "redirect:/";
    53. }
    54. }

    IngredientByIdConverter.java

    1. package com.wdh.tacocloud.controller;
    2. import com.wdh.tacocloud.data.IngredientRepository;
    3. import com.wdh.tacocloud.model.Ingredient;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.core.convert.converter.Converter;
    6. import org.springframework.stereotype.Component;
    7. /**
    8. * @author WangDH
    9. * @create 2022-08-26 11:31
    10. */
    11. @Component
    12. public class IngredientByIdConverter implements Converter<String, Ingredient> {
    13. private IngredientRepository ingredientRepo;
    14. @Autowired
    15. public IngredientByIdConverter(IngredientRepository ingredientRepo) {
    16. this.ingredientRepo = ingredientRepo;
    17. }
    18. @Override
    19. public Ingredient convert(String id) {
    20. return ingredientRepo.findById(id).get();
    21. }
    22. }

    前端 templates

    registration.html

    tacocloud_jpa\src\main\resources\templates\registration.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Register - Taco Cloud</title>
    6. </head>
    7. <body>
    8. <h1>Register</h1>
    9. <img th:src="@{/images/debug.png}" />
    10. <form method="post" th:action="@{/register}" id="registerForm">
    11. <label for="username">UserName:</label>
    12. <input type="text" name="username" /><br/>
    13. <label for="password">password:</label>
    14. <input type="password" name="password" /><br/>
    15. <label for="confirm">confirm password:</label>
    16. <input type="password" name="confirm" /><br/>
    17. <input type="submit" value="Register" />
    18. </form>
    19. </body>
    20. </html>

    home.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Taco-Cloud.This is my spring boot home page</title>
    6. </head>
    7. <body>
    8. <h1>Taco-Cloud.hello world! spring boot.Welcome to my site.</h1>
    9. <img th:src="@{/images/debug.png}" />
    10. </body>
    11. </html>

    login.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Login</title>
    6. </head>
    7. <body>
    8. <h1>Login</h1>
    9. <div th:if="${error}">
    10. unable to login.check id and pwd.
    11. </div>
    12. <p>New Here? click <a th:href="@{/register}">here</a> to register.</p>
    13. <form method="post" th:action="@{/login}" id="loginForm">
    14. <label for="username">UserName:</label>
    15. <input type="text" name="username" id="username" /><br/>
    16. <label for="password">password:</label>
    17. <input type="password" name="password" id="password" /><br/>
    18. <input type="submit" value="Login" />
    19. </form>
    20. </body>
    21. </html>

    design.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Taco cloud</title>
    6. <link rel="stylesheet" th:href="@{/styles.css}" />
    7. </head>
    8. <body>
    9. <h2>Design your taco,4</h2>
    10. <img th:src="@{/images/debug.png}" style="width: 20px;height: 20px;" />
    11. <form method="post" th:object="${taco}" th:action="@{/design}" id="tacoForm">
    12. <span class="validationError"
    13. th:if="${#fields.hasErrors('ingredients')}" th:errors="*{ingredients}">
    14. Ingredient Errors.
    15. </span>
    16. <div class="grid">
    17. <div class="ingredient-group" id="wraps">
    18. <h3>Designate your wrap:</h3>
    19. <div th:each="ingredient:${wrap}">
    20. <input name="ingredients" type="checkbox" th:value="${ingredient.id}" />
    21. <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    22. </div>
    23. </div>
    24. <div class="ingredient-group" id="proteins">
    25. <h3>Designate your proteins:</h3>
    26. <div th:each="ingredient:${protein}">
    27. <input name="ingredients" type="checkbox" th:value="${ingredient.id}" />
    28. <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    29. </div>
    30. </div>
    31. <div class="ingredient-group" id="cheeses">
    32. <h3>Designate your cheeses:</h3>
    33. <div th:each="ingredient:${cheese}">
    34. <input name="ingredients" type="checkbox" th:value="${ingredient.id}" />
    35. <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    36. </div>
    37. </div>
    38. <div class="ingredient-group" id="veggies">
    39. <h3>Designate your veggies:</h3>
    40. <div th:each="ingredient:${veggies}">
    41. <input name="ingredients" type="checkbox" th:value="${ingredient.id}" />
    42. <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    43. </div>
    44. </div>
    45. <div class="ingredient-group" id="sauces">
    46. <h3>Designate your sauces:</h3>
    47. <div th:each="ingredient:${sauce}">
    48. <input name="ingredients" type="checkbox" th:value="${ingredient.id}" />
    49. <span th:text="${ingredient.name}">INGREDIENT</span><br/>
    50. </div>
    51. </div>
    52. </div>
    53. <div>
    54. <h3>Name your taco creation:</h3>
    55. <input type="text" th:field="*{name}"/><br/>
    56. <span th:text="${#fields.hasErrors('name')}">XXX</span>
    57. <span class="validationError"
    58. th:if="${#fields.hasErrors('name')}" th:errors="*{name}">
    59. Name Errors.
    60. </span>
    61. <input type="hidden" name="_csrf" th:value="${_csrf.token}" />
    62. <button>Submit your taco</button>
    63. </div>
    64. </form>
    65. <hr />
    66. <br/>
    67. <form method="post" th:action="@{/logout}" id="logoutForm">
    68. <h2>The login username=<span th:text="${user.username}"></span></h2>
    69. <br>
    70. <input type="submit" value="Logout" />
    71. </form>
    72. </body>
    73. </html>

    orderForm.html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Taco Cloud-Order Form</title>
    6. <link rel="stylesheet" th:href="@{/styles.css}"/>
    7. </head>
    8. <body>
    9. <form method="post" th:action="@{/orders}" th:object="${order}">
    10. <h2>Order your taco creations:</h2>
    11. <img th:src="@{/images/debug.png}" style="width: 20px;height: 20px;"/>
    12. <a th:href="@{/design}" id="another">Design another taco</a><br/>
    13. <div th:if="${#fields.hasErrors()}">
    14. <span class="validationError">
    15. Please correct the problems below and resubmit.
    16. </span>
    17. </div>
    18. <h3>Deliver my taco masterpieces to ...</h3>
    19. <label for="deliveryName">Name: </label>
    20. <input type="text" th:field="*{deliveryName}"/>
    21. <span class="validationError"
    22. th:if="${#fields.hasErrors('deliveryName')}"
    23. th:errors="*{deliveryName}">Name Error</span>
    24. <br/>
    25. <label for="deliveryStreet">Street address: </label>
    26. <input type="text" th:field="*{deliveryStreet}"/>
    27. <span class="validationError"
    28. th:if="${#fields.hasErrors('deliveryStreet')}"
    29. th:errors="*{deliveryStreet}">Street Error</span>
    30. <br/>
    31. <label for="deliveryCity">City: </label>
    32. <input type="text" th:field="*{deliveryCity}"/>
    33. <span class="validationError"
    34. th:if="${#fields.hasErrors('deliveryCity')}"
    35. th:errors="*{deliveryCity}">City Error</span>
    36. <br/>
    37. <label for="deliveryState">State: </label>
    38. <input type="text" th:field="*{deliveryState}"/>
    39. <span class="validationError"
    40. th:if="${#fields.hasErrors('deliveryState')}"
    41. th:errors="*{deliveryState}">State Error</span>
    42. <br/>
    43. <label for="deliveryZip">Zip code: </label>
    44. <input type="text" th:field="*{deliveryZip}"/>
    45. <span class="validationError"
    46. th:if="${#fields.hasErrors('deliveryZip')}"
    47. th:errors="*{deliveryZip}">Zip Error</span>
    48. <br/>
    49. <h3>Here is how i will pay ...</h3>
    50. <label for="ccNumber" >Credit Card#:</label>
    51. <input type="text" th:field="*{ccNumber}"/>
    52. <span class="validationError"
    53. th:if="${#fields.hasErrors('ccNumber')}"
    54. th:errors="*{ccNumber}">CC Num Error</span>
    55. <br/>
    56. <label for="ccExpiration" >Expiration:</label>
    57. <input type="text" th:field="*{ccExpiration}"/>
    58. <span class="validationError"
    59. th:if="${#fields.hasErrors('ccExpiration')}" th:errors="*{ccExpiration}">
    60. Expiration Errors.
    61. </span>
    62. <br/>
    63. <label for="ccCVV" >ccCVV:</label>
    64. <input type="text" th:field="*{ccCVV}"/>
    65. <span class="validationError"
    66. th:if="${#fields.hasErrors('ccCVV')}" th:errors="*{ccCVV}">
    67. CVV Errors.
    68. </span>
    69. <br/>
    70. <input type="submit" value="Submit order" />
    71. </form>
    72. </body>
    73. </html>

    部分sql

    schema.sql

    路径:\tacocloud_jpa\src\main\resources\schema.sql

    在程序启动时会自动创建到H2 database中

    1. create table if not exists Ingredient (
    2. id varchar(4) not null PRIMARY KEY,
    3. name varchar(25) not null,
    4. mytype varchar(10) not null
    5. );
    6. create table if not exists Taco (
    7. id identity,
    8. name varchar(50) not null,
    9. createdAt timestamp not null
    10. );
    11. create table if not exists Taco_Ingredients (
    12. taco bigint not null,
    13. ingredient varchar(4) not null
    14. );
    15. alter table Taco_Ingredients
    16. add foreign key (taco) references Taco(id);
    17. alter table Taco_Ingredients
    18. add foreign key (ingredient) references Ingredient(id);
    19. create table if not exists Taco_Order (
    20. id identity,
    21. deliveryName varchar(50) not null,
    22. deliveryStreet varchar(50) not null,
    23. deliveryCity varchar(50) not null,
    24. deliveryState varchar(2) not null,
    25. deliveryZip varchar(10) not null,
    26. ccNumber varchar(16) not null,
    27. ccExpiration varchar(5) not null,
    28. ccCVV varchar(3) not null,
    29. placedAt timestamp not null
    30. );
    31. create table if not exists Taco_Order_Tacos (
    32. tacoOrder bigint not null,
    33. taco bigint not null
    34. );
    35. alter table Taco_Order_Tacos
    36. add foreign key (tacoOrder) references Taco_Order(id);
    37. alter table Taco_Order_Tacos
    38. add foreign key (taco) references Taco(id);

    data.sql

    路径:tacocloud_jpa\src\main\resources\data.sql

    注意,当使用jpa时该文件不会自动执行插入数据操作,需要登录http://localhost:8080/h2-console页面后手动拷贝此sql执行数据新增,以便design页面加载后有数据。

    1. delete from Taco_Order_Tacos;
    2. delete from Taco_Ingredients;
    3. delete from Taco;
    4. delete from Taco_Order;
    5. delete from Ingredient;
    6. insert into Ingredient (id, name, mytype)
    7. values ('FLTO', 'Flour Tortilla11', 'WRAP');
    8. insert into Ingredient (id, name, mytype)
    9. values ('COTO', 'Corn Tortilla22', 'WRAP');
    10. insert into Ingredient (id, name, mytype)
    11. values ('GRBF', 'Ground Beef33', 'PROTEIN');
    12. insert into Ingredient (id, name, mytype)
    13. values ('CARN', 'Carnitas', 'PROTEIN');
    14. insert into Ingredient (id, name, mytype)
    15. values ('TMTO', 'Diced Tomatoes', 'VEGGIES');
    16. insert into Ingredient (id, name, mytype)
    17. values ('LETC', 'Lettuce', 'VEGGIES');
    18. insert into Ingredient (id, name, mytype)
    19. values ('CHED', 'Cheddar', 'CHEESE');
    20. insert into Ingredient (id, name, mytype)
    21. values ('JACK', 'Monterrey Jack', 'CHEESE');
    22. insert into Ingredient (id, name, mytype)
    23. values ('SLSA', 'Salsa', 'SAUCE');
    24. insert into Ingredient (id, name, mytype)
    25. values ('SRCR', 'Sour Cream', 'SAUCE');

    启动运行

    查看IDEA中提示【Tomcat started on port(s): 8080 (http) with context path ''】【Completed initialization in 153 ms】类似字样后就可打开浏览器访问此应用了。

    未登录时:浏览器直接输入内页地址【http://localhost:8080/design】会被强制跳转到登录也【http://localhost:8080/login

    注册页:【http://localhost:8080/register

    登录页:【http://localhost:8080/login

    登录后默认跳转至:【http://localhost:8080/design

    内页(design.html)输入相关信息后提交会跳转至【http://localhost:8080/orders/current

    登出后会跳转至【http://localhost:8080/

    IDEA启动程序后的日志

    1. "C:\Program Files\Java\jdk1.8.0_111\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:D:\JavaDevEnv\JetBrains\IntelliJ IDEA 2018.3.6\lib\idea_rt.jar=11189:D:\JavaDevEnv\JetBrains\IntelliJ IDEA 2018.3.6\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_111\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_111\jre\lib\rt.jar;D:\JavaWorkspace\IdeaProjects\SpringInAction\tacocloud_jpa\target\classes;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-thymeleaf\2.3.7.RELEASE\spring-boot-starter-thymeleaf-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter\2.3.7.RELEASE\spring-boot-starter-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-logging\2.3.7.RELEASE\spring-boot-starter-logging-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\JavaDevEnv\maven_repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\JavaDevEnv\maven_repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;D:\JavaDevEnv\maven_repository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;D:\JavaDevEnv\maven_repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\JavaDevEnv\maven_repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\JavaDevEnv\maven_repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;D:\JavaDevEnv\maven_repository\org\thymeleaf\thymeleaf-spring5\3.0.11.RELEASE\thymeleaf-spring5-3.0.11.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\thymeleaf\thymeleaf\3.0.11.RELEASE\thymeleaf-3.0.11.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\attoparser\attoparser\2.0.5.RELEASE\attoparser-2.0.5.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\unbescape\unbescape\1.1.6.RELEASE\unbescape-1.1.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\JavaDevEnv\maven_repository\org\thymeleaf\extras\thymeleaf-extras-java8time\3.0.4.RELEASE\thymeleaf-extras-java8time-3.0.4.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-web\2.3.7.RELEASE\spring-boot-starter-web-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-json\2.3.7.RELEASE\spring-boot-starter-json-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\core\jackson-databind\2.11.3\jackson-databind-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\core\jackson-annotations\2.11.3\jackson-annotations-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\core\jackson-core\2.11.3\jackson-core-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.3\jackson-datatype-jdk8-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.3\jackson-datatype-jsr310-2.11.3.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.3\jackson-module-parameter-names-2.11.3.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.7.RELEASE\spring-boot-starter-tomcat-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.41\tomcat-embed-core-9.0.41.jar;D:\JavaDevEnv\maven_repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.41\tomcat-embed-websocket-9.0.41.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-web\5.2.12.RELEASE\spring-web-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-beans\5.2.12.RELEASE\spring-beans-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-webmvc\5.2.12.RELEASE\spring-webmvc-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-context\5.2.12.RELEASE\spring-context-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-expression\5.2.12.RELEASE\spring-expression-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-devtools\2.3.7.RELEASE\spring-boot-devtools-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot\2.3.7.RELEASE\spring-boot-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-autoconfigure\2.3.7.RELEASE\spring-boot-autoconfigure-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\projectlombok\lombok\1.18.24\lombok-1.18.24.jar;D:\JavaDevEnv\maven_repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;D:\JavaDevEnv\maven_repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;D:\JavaDevEnv\maven_repository\net\bytebuddy\byte-buddy\1.10.18\byte-buddy-1.10.18.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-core\5.2.12.RELEASE\spring-core-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-jcl\5.2.12.RELEASE\spring-jcl-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-validation\2.3.7.RELEASE\spring-boot-starter-validation-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;D:\JavaDevEnv\maven_repository\org\hibernate\validator\hibernate-validator\6.1.6.Final\hibernate-validator-6.1.6.Final.jar;D:\JavaDevEnv\maven_repository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;D:\JavaDevEnv\maven_repository\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar;D:\JavaDevEnv\maven_repository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-data-jpa\2.3.7.RELEASE\spring-boot-starter-data-jpa-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-aop\2.3.7.RELEASE\spring-boot-starter-aop-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-jdbc\2.3.7.RELEASE\spring-boot-starter-jdbc-2.3.7.RELEASE.jar;D:\JavaDevEnv\maven_repository\com\zaxxer\HikariCP\3.4.5\HikariCP-3.4.5.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-jdbc\5.2.12.RELEASE\spring-jdbc-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\jakarta\transaction\jakarta.transaction-api\1.3.3\jakarta.transaction-api-1.3.3.jar;D:\JavaDevEnv\maven_repository\jakarta\persistence\jakarta.persistence-api\2.2.3\jakarta.persistence-api-2.2.3.jar;D:\JavaDevEnv\maven_repository\org\hibernate\hibernate-core\5.4.25.Final\hibernate-core-5.4.25.Final.jar;D:\JavaDevEnv\maven_repository\org\javassist\javassist\3.27.0-GA\javassist-3.27.0-GA.jar;D:\JavaDevEnv\maven_repository\antlr\antlr\2.7.7\antlr-2.7.7.jar;D:\JavaDevEnv\maven_repository\org\jboss\jandex\2.1.3.Final\jandex-2.1.3.Final.jar;D:\JavaDevEnv\maven_repository\org\dom4j\dom4j\2.1.3\dom4j-2.1.3.jar;D:\JavaDevEnv\maven_repository\org\hibernate\common\hibernate-commons-annotations\5.1.2.Final\hibernate-commons-annotations-5.1.2.Final.jar;D:\JavaDevEnv\maven_repository\org\glassfish\jaxb\jaxb-runtime\2.3.3\jaxb-runtime-2.3.3.jar;D:\JavaDevEnv\maven_repository\org\glassfish\jaxb\txw2\2.3.3\txw2-2.3.3.jar;D:\JavaDevEnv\maven_repository\com\sun\istack\istack-commons-runtime\3.0.11\istack-commons-runtime-3.0.11.jar;D:\JavaDevEnv\maven_repository\com\sun\activation\jakarta.activation\1.2.2\jakarta.activation-1.2.2.jar;D:\JavaDevEnv\maven_repository\org\springframework\data\spring-data-jpa\2.3.6.RELEASE\spring-data-jpa-2.3.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\data\spring-data-commons\2.3.6.RELEASE\spring-data-commons-2.3.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-orm\5.2.12.RELEASE\spring-orm-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-tx\5.2.12.RELEASE\spring-tx-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-aspects\5.2.12.RELEASE\spring-aspects-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\eclipse\persistence\eclipselink\4.0.0-M3\eclipselink-4.0.0-M3.jar;D:\JavaDevEnv\maven_repository\com\sun\xml\bind\jaxb-xjc\4.0.0-M3\jaxb-xjc-4.0.0-M3.jar;D:\JavaDevEnv\maven_repository\com\sun\xml\bind\jaxb-core\4.0.0-M3\jaxb-core-4.0.0-M3.jar;D:\JavaDevEnv\maven_repository\org\eclipse\angus\angus-activation\1.0.0\angus-activation-1.0.0.jar;D:\JavaDevEnv\maven_repository\com\h2database\h2\2.1.214\h2-2.1.214.jar;D:\JavaDevEnv\maven_repository\org\springframework\boot\spring-boot-starter-security\2.7.3\spring-boot-starter-security-2.7.3.jar;D:\JavaDevEnv\maven_repository\org\springframework\spring-aop\5.2.12.RELEASE\spring-aop-5.2.12.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\security\spring-security-config\5.3.6.RELEASE\spring-security-config-5.3.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\security\spring-security-core\5.3.6.RELEASE\spring-security-core-5.3.6.RELEASE.jar;D:\JavaDevEnv\maven_repository\org\springframework\security\spring-security-web\5.3.6.RELEASE\spring-security-web-5.3.6.RELEASE.jar" com.wdh.tacocloud.TacocloudApplication
    2. . ____ _ __ _ _
    3. /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
    4. ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    5. \\/ ___)| |_)| | | | | || (_| | ) ) ) )
    6. ' |____| .__|_| |_|_| |_\__, | / / / /
    7. =========|_|==============|___/=/_/_/_/
    8. :: Spring Boot :: (v2.3.7.RELEASE)
    9. 2022-09-07 13:57:02.885 INFO 1108 --- [ restartedMain] com.wdh.tacocloud.TacocloudApplication : Starting TacocloudApplication on 14JPYI7CBESDNFK with PID 1108 (D:\JavaWorkspace\IdeaProjects\SpringInAction\tacocloud_jpa\target\classes started by Administrator in D:\JavaWorkspace\IdeaProjects\SpringInAction\tacocloud_jpa)
    10. 2022-09-07 13:57:02.885 INFO 1108 --- [ restartedMain] com.wdh.tacocloud.TacocloudApplication : No active profile set, falling back to default profiles: default
    11. 2022-09-07 13:57:02.948 INFO 1108 --- [ restartedMain] o.s.b.devtools.restart.ChangeableUrls : The Class-Path manifest attribute in D:\JavaDevEnv\maven_repository\com\sun\xml\bind\jaxb-xjc\4.0.0-M3\jaxb-xjc-4.0.0-M3.jar referenced one or more files that do not exist: file:/D:/JavaDevEnv/maven_repository/com/sun/xml/bind/jaxb-xjc/4.0.0-M3/jaxb-core.jar,file:/D:/JavaDevEnv/maven_repository/com/sun/xml/bind/jaxb-xjc/4.0.0-M3/jaxb-impl.jar
    12. 2022-09-07 13:57:02.948 INFO 1108 --- [ restartedMain] o.s.b.devtools.restart.ChangeableUrls : The Class-Path manifest attribute in D:\JavaDevEnv\maven_repository\com\sun\xml\bind\jaxb-core\4.0.0-M3\jaxb-core-4.0.0-M3.jar referenced one or more files that do not exist: file:/D:/JavaDevEnv/maven_repository/com/sun/xml/bind/jaxb-core/4.0.0-M3/jakarta.activation-api.jar,file:/D:/JavaDevEnv/maven_repository/com/sun/xml/bind/jaxb-core/4.0.0-M3/jakarta.xml.bind-api.jar
    13. 2022-09-07 13:57:02.948 INFO 1108 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
    14. 2022-09-07 13:57:02.948 INFO 1108 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
    15. 2022-09-07 13:57:03.827 INFO 1108 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
    16. 2022-09-07 13:57:03.890 INFO 1108 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 45ms. Found 4 JPA repository interfaces.
    17. 2022-09-07 13:57:04.404 INFO 1108 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
    18. 2022-09-07 13:57:04.404 INFO 1108 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
    19. 2022-09-07 13:57:04.404 INFO 1108 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
    20. 2022-09-07 13:57:04.482 INFO 1108 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
    21. 2022-09-07 13:57:04.482 INFO 1108 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1534 ms
    22. 2022-09-07 13:57:04.529 INFO 1108 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
    23. 2022-09-07 13:57:04.623 INFO 1108 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
    24. 2022-09-07 13:57:04.732 INFO 1108 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:c573c85b-45f1-4306-b148-51094d4aa9ce'
    25. 2022-09-07 13:57:04.779 INFO 1108 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
    26. 2022-09-07 13:57:04.841 INFO 1108 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
    27. 2022-09-07 13:57:04.872 INFO 1108 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.25.Final
    28. 2022-09-07 13:57:04.966 INFO 1108 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
    29. 2022-09-07 13:57:05.060 INFO 1108 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
    30. Hibernate:
    31. drop table if exists ingredient CASCADE
    32. Hibernate:
    33. drop table if exists taco CASCADE
    34. Hibernate:
    35. drop table if exists taco_ingredients CASCADE
    36. Hibernate:
    37. drop table if exists taco_order CASCADE
    38. Hibernate:
    39. drop table if exists taco_order_tacos CASCADE
    40. Hibernate:
    41. drop table if exists tuser CASCADE
    42. Hibernate:
    43. drop sequence if exists hibernate_sequence
    44. Hibernate: create sequence hibernate_sequence start with 1 increment by 1
    45. Hibernate:
    46. create table ingredient (
    47. id varchar(255) not null,
    48. mytype varchar(255),
    49. name varchar(255),
    50. primary key (id)
    51. )
    52. Hibernate:
    53. create table taco (
    54. id bigint not null,
    55. created_at timestamp,
    56. name varchar(255) not null,
    57. primary key (id)
    58. )
    59. Hibernate:
    60. create table taco_ingredients (
    61. taco_id bigint not null,
    62. ingredients_id varchar(255) not null
    63. )
    64. Hibernate:
    65. create table taco_order (
    66. id bigint not null,
    67. cccvv varchar(255),
    68. cc_expiration varchar(255),
    69. cc_number varchar(255),
    70. delivery_city varchar(255),
    71. delivery_name varchar(255),
    72. delivery_state varchar(255),
    73. delivery_street varchar(255),
    74. delivery_zip varchar(255),
    75. placed_at timestamp,
    76. user_id bigint,
    77. primary key (id)
    78. )
    79. Hibernate:
    80. create table taco_order_tacos (
    81. order_id bigint not null,
    82. tacos_id bigint not null
    83. )
    84. Hibernate:
    85. create table tuser (
    86. id bigint not null,
    87. password varchar(255),
    88. username varchar(255),
    89. primary key (id)
    90. )
    91. Hibernate:
    92. alter table taco_ingredients
    93. add constraint FK7y679y77n5e75s3ss1v7ff14j
    94. foreign key (ingredients_id)
    95. references ingredient
    96. Hibernate:
    97. alter table taco_ingredients
    98. add constraint FK27rycuh3mjaepnba0j6m8xl4q
    99. foreign key (taco_id)
    100. references taco
    101. Hibernate:
    102. alter table taco_order
    103. add constraint FK7aps3q40owoysjeb69gx5puq5
    104. foreign key (user_id)
    105. references tuser
    106. Hibernate:
    107. alter table taco_order_tacos
    108. add constraint FKfwvqtnjfview9e5f7bfqtd1ns
    109. foreign key (tacos_id)
    110. references taco
    111. Hibernate:
    112. alter table taco_order_tacos
    113. add constraint FKcxwvdkndaqmrxcen10vkneexo
    114. foreign key (order_id)
    115. references taco_order
    116. 2022-09-07 13:57:05.652 INFO 1108 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
    117. 2022-09-07 13:57:05.668 INFO 1108 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
    118. 2022-09-07 13:57:05.964 WARN 1108 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
    119. 2022-09-07 13:57:06.105 INFO 1108 --- [ restartedMain] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@33344fa7, org.springframework.security.web.context.SecurityContextPersistenceFilter@1afb6c99, org.springframework.security.web.header.HeaderWriterFilter@2d4fb172, org.springframework.security.web.csrf.CsrfFilter@4e9e193a, org.springframework.security.web.authentication.logout.LogoutFilter@53da7c63, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@275c4b54, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@45640a2a, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@512f5b2f, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@9913c7b, org.springframework.security.web.session.SessionManagementFilter@65dbc852, org.springframework.security.web.access.ExceptionTranslationFilter@1d2c08a7, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@63f7a4d6]
    120. 2022-09-07 13:57:06.214 INFO 1108 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
    121. 2022-09-07 13:57:06.323 WARN 1108 --- [ restartedMain] org.thymeleaf.templatemode.TemplateMode : [THYMELEAF][restartedMain] Template Mode 'HTML5' is deprecated. Using Template Mode 'HTML' instead.
    122. 2022-09-07 13:57:06.401 INFO 1108 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
    123. 2022-09-07 13:57:06.417 INFO 1108 --- [ restartedMain] com.wdh.tacocloud.TacocloudApplication : Started TacocloudApplication in 3.836 seconds (JVM running for 4.49)
    124. 2022-09-07 13:57:44.806 INFO 1108 --- [nio-8080-exec-7] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
    125. 2022-09-07 13:57:44.807 INFO 1108 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
    126. 2022-09-07 13:57:44.960 INFO 1108 --- [nio-8080-exec-7] o.s.web.servlet.DispatcherServlet : Completed initialization in 153 ms
    127. Hibernate:
    128. call next value for hibernate_sequence
    129. Hibernate:
    130. insert
    131. into
    132. tuser
    133. (password, username, id)
    134. values
    135. (?, ?, ?)
    136. Hibernate:
    137. SELECT
    138. id,
    139. username,
    140. password
    141. FROM
    142. TUSER
    143. where
    144. username=?
    145. Hibernate:
    146. select
    147. ingredient0_.id as id1_0_,
    148. ingredient0_.mytype as mytype2_0_,
    149. ingredient0_.name as name3_0_
    150. from
    151. ingredient ingredient0_
    152. 2022-09-07 13:58:25.797 INFO 1108 --- [nio-8080-exec-8] c.w.t.controller.DesignTacoController : --showDesignForm--strLoginUsername=suser1
    153. Hibernate:
    154. SELECT
    155. id,
    156. username,
    157. password
    158. FROM
    159. TUSER
    160. where
    161. username=?
    162. Hibernate:
    163. select
    164. ingredient0_.id as id1_0_0_,
    165. ingredient0_.mytype as mytype2_0_0_,
    166. ingredient0_.name as name3_0_0_
    167. from
    168. ingredient ingredient0_
    169. where
    170. ingredient0_.id=?
    171. 2022-09-07 13:58:31.962 INFO 1108 --- [nio-8080-exec-4] c.w.t.controller.DesignTacoController : Process design:Taco(id=null, createdAt=null, name=wdhtoco, ingredients=[Ingredient(id=FLTO, name=Flour Tortilla11, mytype=WRAP)])
    172. Hibernate:
    173. call next value for hibernate_sequence
    174. Hibernate:
    175. insert
    176. into
    177. taco
    178. (created_at, name, id)
    179. values
    180. (?, ?, ?)
    181. Hibernate:
    182. insert
    183. into
    184. taco_ingredients
    185. (taco_id, ingredients_id)
    186. values
    187. (?, ?)
    188. Hibernate:
    189. call next value for hibernate_sequence
    190. Hibernate:
    191. insert
    192. into
    193. taco_order
    194. (cccvv, cc_expiration, cc_number, delivery_city, delivery_name, delivery_state, delivery_street, delivery_zip, placed_at, user_id, id)
    195. values
    196. (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    197. Hibernate:
    198. insert
    199. into
    200. taco_order_tacos
    201. (order_id, tacos_id)
    202. values
    203. (?, ?)
    204. 2022-09-07 13:59:04.815 INFO 1108 --- [io-8080-exec-10] c.w.t.controller.OrderController : Order submitted:Order(id=3, placedAt=Wed Sep 07 13:59:04 CST 2022, deliveryName=suser1, deliveryStreet=2, deliveryCity=3, deliveryState=4, deliveryZip=5, ccNumber=4005550000000019, ccExpiration=12/22, ccCVV=123, tacos=[Taco(id=2, createdAt=Wed Sep 07 13:58:31 CST 2022, name=wdhtoco, ingredients=[Ingredient(id=FLTO, name=Flour Tortilla11, mytype=WRAP)])], user=Tuser(id=1, username=suser1, password=0cfb338800503e5f20618ff77aa69868763399a38a3b79e168ff8529e1367ec5d51cf8e638134a99))

  • 相关阅读:
    金仓数据库 KingbaseES SQL 语言参考手册 (19. SQL语句: DROP TABLE 到 LOAD)
    位域(位段)/枚举常量用法官方库例程
    docker MySQL删除数据库时的错误(errno: 39)
    [JSOI2007] 建筑抢修
    【多模态融合】TransFusion学习笔记(1)
    VC++如何使用C++ STL标准模板库中的算法函数(附源码)
    【Spring AOP】暴力打通两个切面之间的通信
    SharpShooter Reports.Web 7.5 Crack
    KNN(k-Nearest Neighbor)算法原理
    Go微服务框架及基础平台选择
  • 原文地址:https://blog.csdn.net/wangdonghao137/article/details/126744509