{"id":268348,"date":"2015-11-17T11:19:04","date_gmt":"2015-11-17T08:19:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=268348"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=268348","title":{"rendered":"Spring 4 MVC, Hibernate: \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u043a\u043e \u043c\u043d\u043e\u0433\u0438\u043c"},"content":{"rendered":"<p>       \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0441\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0432 Hibernate, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446 \u0432 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 Spring 4 MVC. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0432 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u0438 \u0432 \u0431\u044d\u043a-\u044d\u043d\u0434&#8217;\u0430\u0445. \u041c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<p>  \u042d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>org.springframework.core.convert.converter.Converter<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0430\u043c \u0432 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 ID&#8217; \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0430\u0445 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/266\/a3f\/e38\/266a3fe3814a45a9bd4cc69fb035698c.png\"\/><br \/>  <a name=\"habracut\"><\/a><br \/>  \u0411\u044b\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438:<\/p>\n<ul>\n<li>Spring 4.1.7.RELEASE<\/li>\n<li>Hibernate Core 4.3.10.Final<\/li>\n<li>validation-api 1.1.0.Final<\/li>\n<li>hibernate-validator 5.1.3.Final<\/li>\n<li>MySQL Server 5.6<\/li>\n<li>Maven 3<\/li>\n<li>JDK 1.7<\/li>\n<li>NetBeans 8.0.2<\/li>\n<\/ul>\n<p>  \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c.<\/p>\n<h4>\u0428\u0430\u0433 1: \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0445\u0435\u043c\u0443 \u0434\u043b\u044f \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JOIN table<\/h4>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/f43\/b7c\/c5f\/f43b7cc5f2f54776a4e1531f38bbd4e1.png\"\/><\/p>\n<p>  <b>APP_USER<\/b>: \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 [USER,ADMIN,DBA].<br \/>  <b>USER_PROFILE<\/b>: \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438.<br \/>  <b>APP_USER_USER_PROFILE<\/b>: \u042d\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u044e\u0449\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u044b APP_USER \u0438 USER_PROFILE \u0441 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c.<\/p>\n<p>  \u0412 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0432 \u043e\u0434\u043d\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 [\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f] \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"sql\">create table APP_USER (    id BIGINT NOT NULL AUTO_INCREMENT,    sso_id VARCHAR(30) NOT NULL,    password VARCHAR(100) NOT NULL,    first_name VARCHAR(30) NOT NULL,    last_name  VARCHAR(30) NOT NULL,    email VARCHAR(30) NOT NULL,    PRIMARY KEY (id),    UNIQUE (sso_id) );       create table USER_PROFILE(    id BIGINT NOT NULL AUTO_INCREMENT,    type VARCHAR(30) NOT NULL,    PRIMARY KEY (id),    UNIQUE (type) );       CREATE TABLE APP_USER_USER_PROFILE (     user_id BIGINT NOT NULL,     user_profile_id BIGINT NOT NULL,     PRIMARY KEY (user_id, user_profile_id),     CONSTRAINT FK_APP_USER FOREIGN KEY (user_id) REFERENCES APP_USER (id),     CONSTRAINT FK_USER_PROFILE FOREIGN KEY (user_profile_id) REFERENCES USER_PROFILE (id) );   \/* Populate USER_PROFILE Table *\/ INSERT INTO USER_PROFILE(type) VALUES ('USER');    INSERT INTO USER_PROFILE(type) VALUES ('ADMIN');    INSERT INTO USER_PROFILE(type) VALUES ('DBA');   commit; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 2: \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430<\/h4>\n<p>  \u0424\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/f21\/d25\/3f6\/f21d253f6eae4b259d6cfbd5f5d2d5aa.png\"\/><\/p>\n<h4>\u0428\u0430\u0433 3: \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 pom.xml, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/h4>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">pom.xml<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;project xsi:schemaLocation=&quot;http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd&quot;     xmlns=&quot;http:\/\/maven.apache.org\/POM\/4.0.0&quot; xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot;&gt;       &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;     &lt;groupId&gt;com.websystique.springmvc&lt;\/groupId&gt;     &lt;artifactId&gt;SpringMVCHibernateManyToManyCRUDExample&lt;\/artifactId&gt;     &lt;packaging&gt;war&lt;\/packaging&gt;     &lt;version&gt;1.0.0&lt;\/version&gt;     &lt;name&gt;SpringMVCHibernateManyToManyCRUDExample&lt;\/name&gt;       &lt;properties&gt;         &lt;springframework.version&gt;4.1.7.RELEASE&lt;\/springframework.version&gt;         &lt;hibernate.version&gt;4.3.10.Final&lt;\/hibernate.version&gt;         &lt;mysql.connector.version&gt;5.1.31&lt;\/mysql.connector.version&gt;     &lt;\/properties&gt;       &lt;dependencies&gt;         &lt;!-- Spring --&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework&lt;\/groupId&gt;             &lt;artifactId&gt;spring-core&lt;\/artifactId&gt;             &lt;version&gt;${springframework.version}&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework&lt;\/groupId&gt;             &lt;artifactId&gt;spring-web&lt;\/artifactId&gt;             &lt;version&gt;${springframework.version}&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework&lt;\/groupId&gt;             &lt;artifactId&gt;spring-webmvc&lt;\/artifactId&gt;             &lt;version&gt;${springframework.version}&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework&lt;\/groupId&gt;             &lt;artifactId&gt;spring-tx&lt;\/artifactId&gt;             &lt;version&gt;${springframework.version}&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework&lt;\/groupId&gt;             &lt;artifactId&gt;spring-orm&lt;\/artifactId&gt;             &lt;version&gt;${springframework.version}&lt;\/version&gt;         &lt;\/dependency&gt;           &lt;!-- Hibernate --&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.hibernate&lt;\/groupId&gt;             &lt;artifactId&gt;hibernate-core&lt;\/artifactId&gt;             &lt;version&gt;${hibernate.version}&lt;\/version&gt;         &lt;\/dependency&gt;           &lt;!-- jsr303 validation --&gt;         &lt;dependency&gt;             &lt;groupId&gt;javax.validation&lt;\/groupId&gt;             &lt;artifactId&gt;validation-api&lt;\/artifactId&gt;             &lt;version&gt;1.1.0.Final&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.hibernate&lt;\/groupId&gt;             &lt;artifactId&gt;hibernate-validator&lt;\/artifactId&gt;             &lt;version&gt;5.1.3.Final&lt;\/version&gt;         &lt;\/dependency&gt;           &lt;!-- MySQL --&gt;         &lt;dependency&gt;             &lt;groupId&gt;mysql&lt;\/groupId&gt;             &lt;artifactId&gt;mysql-connector-java&lt;\/artifactId&gt;             &lt;version&gt;${mysql.connector.version}&lt;\/version&gt;         &lt;\/dependency&gt;           &lt;!-- Servlet+JSP+JSTL --&gt;         &lt;dependency&gt;             &lt;groupId&gt;javax.servlet&lt;\/groupId&gt;             &lt;artifactId&gt;javax.servlet-api&lt;\/artifactId&gt;             &lt;version&gt;3.1.0&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;javax.servlet.jsp&lt;\/groupId&gt;             &lt;artifactId&gt;javax.servlet.jsp-api&lt;\/artifactId&gt;             &lt;version&gt;2.3.1&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;javax.servlet&lt;\/groupId&gt;             &lt;artifactId&gt;jstl&lt;\/artifactId&gt;             &lt;version&gt;1.2&lt;\/version&gt;         &lt;\/dependency&gt;               &lt;\/dependencies&gt;       &lt;build&gt;         &lt;pluginManagement&gt;             &lt;plugins&gt;                 &lt;plugin&gt;                     &lt;groupId&gt;org.apache.maven.plugins&lt;\/groupId&gt;                     &lt;artifactId&gt;maven-war-plugin&lt;\/artifactId&gt;                     &lt;version&gt;2.4&lt;\/version&gt;                     &lt;configuration&gt;                         &lt;warSourceDirectory&gt;src\/main\/webapp&lt;\/warSourceDirectory&gt;                         &lt;warName&gt;SpringMVCHibernateManyToManyCRUDExample&lt;\/warName&gt;                         &lt;failOnMissingWebXml&gt;false&lt;\/failOnMissingWebXml&gt;                     &lt;\/configuration&gt;                 &lt;\/plugin&gt;             &lt;\/plugins&gt;         &lt;\/pluginManagement&gt;         &lt;finalName&gt;SpringMVCHibernateManyToManyCRUDExample&lt;\/finalName&gt;     &lt;\/build&gt; &lt;\/project&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 4: \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043c\u043e\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432<\/h4>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043a\u043b\u0430\u0441\u0441 User<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package com.websystique.springmvc.model;   import java.util.HashSet; import java.util.Set;   import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table;   import org.hibernate.validator.constraints.NotEmpty;   @Entity @Table(name=&quot;APP_USER&quot;) public class User {       @Id @GeneratedValue(strategy=GenerationType.IDENTITY)     private Integer id;       @NotEmpty     @Column(name=&quot;SSO_ID&quot;, unique=true, nullable=false)     private String ssoId;           @NotEmpty     @Column(name=&quot;PASSWORD&quot;, nullable=false)     private String password;               @NotEmpty     @Column(name=&quot;FIRST_NAME&quot;, nullable=false)     private String firstName;       @NotEmpty     @Column(name=&quot;LAST_NAME&quot;, nullable=false)     private String lastName;       @NotEmpty     @Column(name=&quot;EMAIL&quot;, nullable=false)     private String email;       @NotEmpty     @ManyToMany(fetch = FetchType.LAZY)     @JoinTable(name = &quot;APP_USER_USER_PROFILE&quot;,               joinColumns = { @JoinColumn(name = &quot;USER_ID&quot;) },               inverseJoinColumns = { @JoinColumn(name = &quot;USER_PROFILE_ID&quot;) })     private Set&lt;UserProfile&gt; userProfiles = new HashSet&lt;UserProfile&gt;();       public Integer getId() {         return id;     }       public void setId(Integer id) {         this.id = id;     }       public String getSsoId() {         return ssoId;     }       public void setSsoId(String ssoId) {         this.ssoId = ssoId;     }       public String getPassword() {         return password;     }       public void setPassword(String password) {         this.password = password;     }       public String getFirstName() {         return firstName;     }       public void setFirstName(String firstName) {         this.firstName = firstName;     }       public String getLastName() {         return lastName;     }       public void setLastName(String lastName) {         this.lastName = lastName;     }       public String getEmail() {         return email;     }       public void setEmail(String email) {         this.email = email;     }       public Set&lt;UserProfile&gt; getUserProfiles() {         return userProfiles;     }       public void setUserProfiles(Set&lt;UserProfile&gt; userProfiles) {         this.userProfiles = userProfiles;     }       @Override     public int hashCode() {         final int prime = 31;         int result = 1;         result = prime * result + ((id == null) ? 0 : id.hashCode());         result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode());         return result;     }       @Override     public boolean equals(Object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (!(obj instanceof User))             return false;         User other = (User) obj;         if (id == null) {             if (other.id != null)                 return false;         } else if (!id.equals(other.id))             return false;         if (ssoId == null) {             if (other.ssoId != null)                 return false;         } else if (!ssoId.equals(other.ssoId))             return false;         return true;     }       @Override     public String toString() {         return &quot;User [id=&quot; + id + &quot;, ssoId=&quot; + ssoId + &quot;, password=&quot; + password                 + &quot;, firstName=&quot; + firstName + &quot;, lastName=&quot; + lastName                 + &quot;, email=&quot; + email + &quot;]&quot;;     }   } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435, \u043a\u0430\u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e userProfiles \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f c \u00ab\u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c\u00bb.<\/p>\n<p>  <code>@ManyToMany<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 [USER, ADMIN, DBA], \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a, \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c.<code>@JoinTable<\/code> \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 \u043a \u0438\u0445 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u043c. \u042d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0432\u043b\u0430\u0434\u0435\u044e\u0449\u0435\u0439 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439. <code>joinColumns<\/code> \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043a \u0438\u043c\u0435\u043d\u0438 \u0441\u0442\u043e\u043b\u0431\u0446\u0430 \u043d\u0430 \u0432\u043b\u0430\u0434\u0435\u044e\u0449\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 (ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f), \u0430 \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f <code>joinColumns<\/code> \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043a\u043e\u043b\u043e\u043d\u043a\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f (ID \u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f). \u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u044d\u0442\u043e\u0439 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u044e\u0449\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0435\u0441\u0442\u044c \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 USER_ID \u0438 USER_PROFILE_ID.<\/p>\n<p>  <b>\u00ab\u041b\u0435\u043d\u0438\u0432\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u00bb<\/b><\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u043e\u0441\u043e\u0431\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <code>fetch = FetchType.LAZY<\/code>.\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Hibernate_(%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0)\">Hibernate<\/a> \u043e \u00ab\u043b\u0435\u043d\u0438\u0432\u043e\u0439\u00bb \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 userProfile. \u0414\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c. \u0421 \u0442\u0430\u043a\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439, \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f. \u042d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043a \u0433\u0440\u0430\u0444\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u00ab\u0434\u043e\u0440\u043e\u0433\u043e\u0439\u00bb \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439. \u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435\u0441\u044c \u0432 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438 \/ \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438, \u0438 \u0431\u0443\u0434\u0438\u0442\u0435 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, Hibernate \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0445. <\/p>\n<p>  \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435\u0441\u044c \u0432\u043d\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0435\u0441\u0441\u0438\u044f \u0431\u044b\u043b\u0430 \u0437\u0430\u043a\u0440\u044b\u0442\u0430 \/ \u043d\u0435\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439: \u0432\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435\u0441\u044c \u043d\u0430 JSP \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435), \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u0432\u044b \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u0435\u0441\u044c \u0441 <code>org.hibernate.LazyInitializationException \u2013 could not initialize proxy \u2013 no Session<\/code>. \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e, \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u043f\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044e \u0432\u044b\u0437\u043e\u0432\u043e\u0432 <code>Hibernate.initialize(user.getUserProfiles());<\/code> \u0432 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0435\u0430\u043d\u0441\u0435. <\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u0430\u0441\u043a\u0430\u0434. \u042d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443-\u0447\u0442\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <u>\u041e\u0434\u043d\u043e \u0432\u0430\u0436\u043d\u043e\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/u>: \u0412 \u0441\u043b\u0443\u0447\u0430\u0438 \u00ab\u043c\u043d\u043e\u0433\u043e\u00bb \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0439, \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0439\u0442\u0435 \u043c\u0435\u0442\u043e\u0434\u044b hashCode() \u0438 equals(), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u044e\u0442\u0441\u044f Hibernate&#8217;\u043e\u043c \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. <\/p>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 UserProfile<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.model;   import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;   @Entity @Table(name=&quot;USER_PROFILE&quot;) public class UserProfile {       @Id @GeneratedValue(strategy=GenerationType.IDENTITY)     private Integer id;        @Column(name=&quot;TYPE&quot;, length=15, unique=true, nullable=false)     private String type = UserProfileType.USER.getUserProfileType();           public Integer getId() {         return id;     }       public void setId(Integer id) {         this.id = id;     }       public String getType() {         return type;     }       public void setType(String type) {         this.type = type;     }       @Override     public int hashCode() {         final int prime = 31;         int result = 1;         result = prime * result + ((id == null) ? 0 : id.hashCode());         result = prime * result + ((type == null) ? 0 : type.hashCode());         return result;     }       @Override     public boolean equals(Object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (!(obj instanceof UserProfile))             return false;         UserProfile other = (UserProfile) obj;         if (id == null) {             if (other.id != null)                 return false;         } else if (!id.equals(other.id))             return false;         if (type == null) {             if (other.type != null)                 return false;         } else if (!type.equals(other.type))             return false;         return true;     }       @Override     public String toString() {         return &quot;UserProfile [id=&quot; + id + &quot;, type=&quot; + type + &quot;]&quot;;     }   } <\/code><\/pre>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u0434\u043d\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 (\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u043f\u0440\u043e\u0444\u0438\u043b\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f), \u0442\u043e \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>  <b>UserProfileType<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.model;   public enum UserProfileType {     USER(&quot;USER&quot;),     DBA(&quot;DBA&quot;),     ADMIN(&quot;ADMIN&quot;);           String userProfileType;           private UserProfileType(String userProfileType){         this.userProfileType = userProfileType;     }           public String getUserProfileType(){         return userProfileType;     }       } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 5: \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043b\u043e\u044f <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Data_Access_Object\">DAO<\/a><\/h4>\n<p>  <b>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 UserDao<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.dao;   import java.util.List;   import com.websystique.springmvc.model.User;     public interface UserDao {       User findById(int id);           User findBySSO(String sso);           void save(User user);           void deleteBySSO(String sso);           List&lt;User&gt; findAllUsers();   } <\/code><\/pre>\n<p>  <b>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 UserProfileDao<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.dao;   import java.util.List;   import com.websystique.springmvc.model.UserProfile;     public interface UserProfileDao {       List&lt;UserProfile&gt; findAll();           UserProfile findByType(String type);           UserProfile findById(int id); } <\/code><\/pre>\n<p>  <b>\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 AbstractDao<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.dao;   import java.io.Serializable;   import java.lang.reflect.ParameterizedType;   import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired;   public abstract class AbstractDao&lt;PK extends Serializable, T&gt; {           private final Class&lt;T&gt; persistentClass;           @SuppressWarnings(&quot;unchecked&quot;)     public AbstractDao(){         this.persistentClass =(Class&lt;T&gt;) ((ParameterizedType) this.getClass().getGenericSuperclass   ()).getActualTypeArguments()[1];     }           @Autowired     private SessionFactory sessionFactory;       protected Session getSession(){         return sessionFactory.getCurrentSession();     }       @SuppressWarnings(&quot;unchecked&quot;)     public T getByKey(PK key) {         return (T) getSession().get(persistentClass, key);     }       public void persist(T entity) {         getSession().persist(entity);     }       public void delete(T entity) {         getSession().delete(entity);     }           protected Criteria createEntityCriteria(){         return getSession().createCriteria(persistentClass);     }   } <\/code><\/pre>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 UserDaoImpl<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.dao;   import java.util.List;   import org.hibernate.Criteria; import org.hibernate.Hibernate; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.springframework.stereotype.Repository;   import com.websystique.springmvc.model.User;       @Repository(&quot;userDao&quot;) public class UserDaoImpl extends AbstractDao&lt;Integer, User&gt; implements UserDao {       public User findById(int id) {         User user = getByKey(id);         if(user!=null){             Hibernate.initialize(user.getUserProfiles());         }         return user;     }       public User findBySSO(String sso) {         System.out.println(&quot;SSO : &quot;+sso);         Criteria crit = createEntityCriteria();         crit.add(Restrictions.eq(&quot;ssoId&quot;, sso));         User user = (User)crit.uniqueResult();         if(user!=null){             Hibernate.initialize(user.getUserProfiles());         }         return user;     }       @SuppressWarnings(&quot;unchecked&quot;)     public List&lt;User&gt; findAllUsers() {         Criteria criteria = createEntityCriteria().addOrder(Order.asc(&quot;firstName&quot;));         criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);\/\/To avoid duplicates.         List&lt;User&gt; users = (List&lt;User&gt;) criteria.list();                           return users;     }       public void save(User user) {         persist(user);     }       public void deleteBySSO(String sso) {         Criteria crit = createEntityCriteria();         crit.add(Restrictions.eq(&quot;ssoId&quot;, sso));         User user = (User)crit.uniqueResult();         delete(user);     }   } <\/code><\/pre>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 UserProfileDaoImpl<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.dao;   import java.util.List;   import org.hibernate.Criteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.springframework.stereotype.Repository;   import com.websystique.springmvc.model.UserProfile;       @Repository(&quot;userProfileDao&quot;) public class UserProfileDaoImpl extends AbstractDao&lt;Integer, UserProfile&gt;implements UserProfileDao{       public UserProfile findById(int id) {         return getByKey(id);     }       public UserProfile findByType(String type) {         Criteria crit = createEntityCriteria();         crit.add(Restrictions.eq(&quot;type&quot;, type));         return (UserProfile) crit.uniqueResult();     }           @SuppressWarnings(&quot;unchecked&quot;)     public List&lt;UserProfile&gt; findAll(){         Criteria crit = createEntityCriteria();         crit.addOrder(Order.asc(&quot;type&quot;));         return (List&lt;UserProfile&gt;)crit.list();     }       } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 6: \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u044f<\/h4>\n<p>  <b>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 UserProfileService<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.service;   import java.util.List;   import com.websystique.springmvc.model.UserProfile;     public interface UserProfileService {       UserProfile findById(int id);       UserProfile findByType(String type);           List&lt;UserProfile&gt; findAll();       } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 UserService<\/h4>\n<p>  <\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.service;   import java.util.List;   import com.websystique.springmvc.model.User;     public interface UserService {           User findById(int id);           User findBySSO(String sso);           void saveUser(User user);           void updateUser(User user);           void deleteUserBySSO(String sso);       List&lt;User&gt; findAllUsers();            boolean isUserSSOUnique(Integer id, String sso);   } <\/code><\/pre>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 UserProfileServiceImpl<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.service;   import java.util.List;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;   import com.websystique.springmvc.dao.UserProfileDao; import com.websystique.springmvc.model.UserProfile;     @Service(&quot;userProfileService&quot;) @Transactional public class UserProfileServiceImpl implements UserProfileService{           @Autowired     UserProfileDao dao;           public UserProfile findById(int id) {         return dao.findById(id);     }       public UserProfile findByType(String type){         return dao.findByType(type);     }       public List&lt;UserProfile&gt; findAll() {         return dao.findAll();     } } <\/code><\/pre>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 UserServiceImpl<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.service;   import java.util.List;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;   import com.websystique.springmvc.dao.UserDao; import com.websystique.springmvc.model.User;     @Service(&quot;userService&quot;) @Transactional public class UserServiceImpl implements UserService{       @Autowired     private UserDao dao;       public User findById(int id) {         return dao.findById(id);     }       public User findBySSO(String sso) {         User user = dao.findBySSO(sso);         return user;     }       public void saveUser(User user) {         dao.save(user);     }       \/*      * Since the method is running with Transaction, No need to call hibernate update explicitly.      * Just fetch the entity from db and update it with proper values within transaction.      * It will be updated in db once transaction ends.       *\/     public void updateUser(User user) {         User entity = dao.findById(user.getId());         if(entity!=null){             entity.setSsoId(user.getSsoId());             entity.setPassword(user.getPassword());             entity.setFirstName(user.getFirstName());             entity.setLastName(user.getLastName());             entity.setEmail(user.getEmail());             entity.setUserProfiles(user.getUserProfiles());         }     }             public void deleteUserBySSO(String sso) {         dao.deleteBySSO(sso);     }       public List&lt;User&gt; findAllUsers() {         return dao.findAllUsers();     }       public boolean isUserSSOUnique(Integer id, String sso) {         User user = findBySSO(sso);         return ( user == null || ((id != null) && (user.getId() == id)));     }       } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 7: \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a Hibernate<\/h4>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 HibernateConfiguration<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.configuration;   import java.util.Properties;   import javax.sql.DataSource;   import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.hibernate4.HibernateTransactionManager; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement;   @Configuration @EnableTransactionManagement @ComponentScan({ &quot;com.websystique.springmvc.configuration&quot; }) @PropertySource(value = { &quot;classpath:application.properties&quot; }) public class HibernateConfiguration {       @Autowired     private Environment environment;       @Bean     public LocalSessionFactoryBean sessionFactory() {         LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();         sessionFactory.setDataSource(dataSource());         sessionFactory.setPackagesToScan(new String[] { &quot;com.websystique.springmvc.model&quot; });         sessionFactory.setHibernateProperties(hibernateProperties());         return sessionFactory;      }           @Bean     public DataSource dataSource() {         DriverManagerDataSource dataSource = new DriverManagerDataSource();         dataSource.setDriverClassName(environment.getRequiredProperty(&quot;jdbc.driverClassName&quot;));         dataSource.setUrl(environment.getRequiredProperty(&quot;jdbc.url&quot;));         dataSource.setUsername(environment.getRequiredProperty(&quot;jdbc.username&quot;));         dataSource.setPassword(environment.getRequiredProperty(&quot;jdbc.password&quot;));         return dataSource;     }           private Properties hibernateProperties() {         Properties properties = new Properties();         properties.put(&quot;hibernate.dialect&quot;, environment.getRequiredProperty(&quot;hibernate.dialect&quot;));         properties.put(&quot;hibernate.show_sql&quot;, environment.getRequiredProperty(&quot;hibernate.show_sql&quot;));         properties.put(&quot;hibernate.format_sql&quot;, environment.getRequiredProperty(&quot;hibernate.format_sql&quot;));         return properties;             }           @Bean     @Autowired     public HibernateTransactionManager transactionManager(SessionFactory s) {        HibernateTransactionManager txManager = new HibernateTransactionManager();        txManager.setSessionFactory(s);        return txManager;     } } <\/code><\/pre>\n<p>  \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f Hibernate:<\/p>\n<p>  <code> jdbc.driverClassName = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql:\/\/localhost:3306\/\u0442\u0430\u0431\u043b\u0438\u0446\u0430 jdbc.username = \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c jdbc.password = \u043f\u0430\u0440\u043e\u043b\u044c hibernate.dialect = org.hibernate.dialect.MySQLDialect hibernate.show_sql = true hibernate.format_sql = true <\/code><\/p>\n<h4>\u0428\u0430\u0433 8: \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430<\/h4>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043b\u0430\u0441\u0441 AppController<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package com.websystique.springmvc.controller;   import java.util.List; import java.util.Locale;   import javax.validation.Valid;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.SessionAttributes;   import com.websystique.springmvc.model.User; import com.websystique.springmvc.model.UserProfile; import com.websystique.springmvc.service.UserProfileService; import com.websystique.springmvc.service.UserService;       @Controller @RequestMapping(&quot;\/&quot;) @SessionAttributes(&quot;roles&quot;) public class AppController {       @Autowired     UserService userService;           @Autowired     UserProfileService userProfileService;                 @Autowired     MessageSource messageSource;       \/**      * This method will list all existing users.      *\/     @RequestMapping(value = { &quot;\/&quot;, &quot;\/list&quot; }, method = RequestMethod.GET)     public String listUsers(ModelMap model) {           List&lt;User&gt; users = userService.findAllUsers();         model.addAttribute(&quot;users&quot;, users);         return &quot;userslist&quot;;     }       \/**      * This method will provide the medium to add a new user.      *\/     @RequestMapping(value = { &quot;\/newuser&quot; }, method = RequestMethod.GET)     public String newUser(ModelMap model) {         User user = new User();         model.addAttribute(&quot;user&quot;, user);         model.addAttribute(&quot;edit&quot;, false);         return &quot;registration&quot;;     }       \/**      * This method will be called on form submission, handling POST request for      * saving user in database. It also validates the user input      *\/     @RequestMapping(value = { &quot;\/newuser&quot; }, method = RequestMethod.POST)     public String saveUser(@Valid User user, BindingResult result,             ModelMap model) {           if (result.hasErrors()) {             return &quot;registration&quot;;         }           \/*          * Preferred way to achieve uniqueness of field [sso] should be implementing custom @Unique annotation           * and applying it on field [sso] of Model class [User].          *           * Below mentioned peace of code [if block] is to demonstrate that you can fill custom errors outside the    validation          * framework as well while still using internationalized messages.          *           *\/         if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){             FieldError ssoError =new FieldError(&quot;user&quot;,&quot;ssoId&quot;,messageSource.getMessage(&quot;non.unique.ssoId&quot;, new   String[]{user.getSsoId()}, Locale.getDefault()));             result.addError(ssoError);             return &quot;registration&quot;;         }                   userService.saveUser(user);           model.addAttribute(&quot;success&quot;, &quot;User &quot; + user.getFirstName() + &quot; &quot;+ user.getLastName() + &quot; registered    successfully&quot;);         \/\/return &quot;success&quot;;         return &quot;registrationsuccess&quot;;     }         \/**      * This method will provide the medium to update an existing user.      *\/     @RequestMapping(value = { &quot;\/edit-user-{ssoId}&quot; }, method = RequestMethod.GET)     public String editUser(@PathVariable String ssoId, ModelMap model) {         User user = userService.findBySSO(ssoId);         model.addAttribute(&quot;user&quot;, user);         model.addAttribute(&quot;edit&quot;, true);         return &quot;registration&quot;;     }           \/**      * This method will be called on form submission, handling POST request for      * updating user in database. It also validates the user input      *\/     @RequestMapping(value = { &quot;\/edit-user-{ssoId}&quot; }, method = RequestMethod.POST)     public String updateUser(@Valid User user, BindingResult result,             ModelMap model, @PathVariable String ssoId) {           if (result.hasErrors()) {             return &quot;registration&quot;;         }           \/*\/\/Uncomment below 'if block' if you WANT TO ALLOW UPDATING SSO_ID in UI which is a unique key to a User.         if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){             FieldError ssoError =new FieldError(&quot;user&quot;,&quot;ssoId&quot;,messageSource.getMessage(&quot;non.unique.ssoId&quot;, new    String[]{user.getSsoId()}, Locale.getDefault()));             result.addError(ssoError);             return &quot;registration&quot;;         }*\/           userService.updateUser(user);           model.addAttribute(&quot;success&quot;, &quot;User &quot; + user.getFirstName() + &quot; &quot;+ user.getLastName() + &quot; updated successfully&quot;);         return &quot;registrationsuccess&quot;;     }             \/**      * This method will delete an user by it's SSOID value.      *\/     @RequestMapping(value = { &quot;\/delete-user-{ssoId}&quot; }, method = RequestMethod.GET)     public String deleteUser(@PathVariable String ssoId) {         userService.deleteUserBySSO(ssoId);         return &quot;redirect:\/list&quot;;     }             \/**      * This method will provide UserProfile list to views      *\/     @ModelAttribute(&quot;roles&quot;)     public List&lt;UserProfile&gt; initializeProfiles() {         return userProfileService.findAll();     }   } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u044b\u0448\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 <code>messages.properties<\/code> \u0444\u0430\u0439\u043b\u0435:<br \/>  <code> NotEmpty.user.firstName=\u041f\u043e\u043b\u0435 \u0438\u043c\u044f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c. NotEmpty.user.lastName=\u041f\u043e\u043b\u0435 \u0444\u0430\u043c\u0438\u043b\u0438\u044f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c. NotEmpty.user.email=\u041f\u043e\u043b\u0435 \u043c\u0430\u0438\u043b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c. NotEmpty.user.password=\u041f\u043e\u043b\u0435 \u043f\u0430\u0440\u043e\u043b\u044f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c. NotEmpty.user.ssoId=\u041f\u043e\u043b\u0435 SSO ID \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c. NotEmpty.user.userProfiles=\u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0444\u0438\u043b\u044c. non.unique.ssoId=SSO ID {0} \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0435\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. <\/code><\/p>\n<h4>\u0428\u0430\u0433 9: \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430<\/h4>\n<p>  \u042d\u0442\u043e \u0441\u0435\u0440\u0434\u0446\u0435 \u044d\u0442\u043e \u043f\u043e\u0441\u0442\u0430. \u042d\u0442\u043e \u0437\u0430\u0431\u043e\u0442\u0438\u0442\u0441\u044f \u043e\u0431 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 ID \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 RoleToUserProfileConverter<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.converter;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component;   import com.websystique.springmvc.model.UserProfile; import com.websystique.springmvc.service.UserProfileService;   \/**  * A converter class used in views to map id's to actual userProfile objects.  *\/ @Component public class RoleToUserProfileConverter implements Converter&lt;Object, UserProfile&gt;{       @Autowired     UserProfileService userProfileService;       \/**      * Gets UserProfile by Id      * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)      *\/     public UserProfile convert(Object element) {         Integer id = Integer.parseInt((String)element);         UserProfile profile= userProfileService.findById(id);         System.out.println(&quot;Profile : &quot;+profile);         return profile;     }       } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 10: \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a Spring<\/h4>\n<p>  <b>\u041a\u043b\u0430\u0441\u0441 AppConfig<\/b><\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.configuration;   import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView;   import com.websystique.springmvc.converter.RoleToUserProfileConverter;     @Configuration @EnableWebMvc @ComponentScan(basePackages = &quot;com.websystique.springmvc&quot;) public class AppConfig extends WebMvcConfigurerAdapter{                 @Autowired     RoleToUserProfileConverter roleToUserProfileConverter;             \/**      * Configure ViewResolvers to deliver preferred views.      *\/     @Override     public void configureViewResolvers(ViewResolverRegistry registry) {           InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();         viewResolver.setViewClass(JstlView.class);         viewResolver.setPrefix(&quot;\/WEB-INF\/views\/&quot;);         viewResolver.setSuffix(&quot;.jsp&quot;);         registry.viewResolver(viewResolver);     }           \/**      * Configure ResourceHandlers to serve static resources like CSS\/ Javascript etc...      *\/     @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler(&quot;\/static\/**&quot;).addResourceLocations(&quot;\/static\/&quot;);     }           \/**      * Configure Converter to be used.      * In our example, we need a converter to convert string values[Roles] to UserProfiles in newUser.jsp      *\/     @Override     public void addFormatters(FormatterRegistry registry) {         registry.addConverter(roleToUserProfileConverter);     }             \/**      * Configure MessageSource to lookup any validation\/error message in internationalized property files      *\/     @Bean     public MessageSource messageSource() {         ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();         messageSource.setBasename(&quot;messages&quot;);         return messageSource;     }           \/**Optional. It's only required when handling '.' in @PathVariables which otherwise ignore everything after last '.' in    @PathVaidables argument.      * It's a known bug in Spring [https:\/\/jira.spring.io\/browse\/SPR-6164], still present in Spring 4.1.7.      * This is a workaround for this issue.      *\/     @Override     public void configurePathMatch(PathMatchConfigurer matcher) {         matcher.setUseRegisteredSuffixPatternMatch(true);     } } <\/code><\/pre>\n<p>  \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0432\u0435\u0449\u044c\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0443\u0440\u043e\u043a\u0430\u0445 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 Spring&#8217;a c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <b>addFormatters<\/b>. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 <b>configurePathMatch<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043e\u0431\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u0443\u0442\u044c (\u0445\u043e\u0442\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0443\u0442\u0438) \u0434\u043b\u044f \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0431\u0430\u0433\u0430 \u0432 Spring, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 Spring 4.1.7.RELEASE.<\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 XML, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: <\/p>\n<pre><code class=\"xml\">&lt;mvc:annotation-driven conversion-service=&quot;conversionService&quot;\/&gt;   &lt;bean id=&quot;conversionService&quot; class=&quot;org.springframework.format.support.FormattingConversionServiceFactoryBean&quot;&gt;       &lt;property name=&quot;converters&quot;&gt;         &lt;list&gt;             &lt;bean id=&quot;roleToUserProfile&quot; class=&quot;com.websystique.springsecurity.configuration.RoleToUserProfileConverter&quot; \/&gt;         &lt;\/list&gt;     &lt;\/property&gt; &lt;\/bean&gt; <\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"java\">package com.websystique.springmvc.configuration;   import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;   public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {       @Override     protected Class&lt;?&gt;[] getRootConfigClasses() {         return new Class[] { AppConfig.class };     }        @Override     protected Class&lt;?&gt;[] getServletConfigClasses() {         return null;     }        @Override     protected String[] getServletMappings() {         return new String[] { &quot;\/&quot; };     }   } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 11: \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\/JSP<\/h4>\n<p>  \u0418\u043c\u0435\u0439\u0442\u0435 \u0432\u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <u>Bootstrap<\/u> \u0434\u043b\u044f \u0434\u0438\u0437\u0430\u0439\u043d\u0430 \u0432 JSP.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">userslist.jsp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">&lt;%@ page language=&quot;java&quot; contentType=&quot;text\/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&gt; &lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http:\/\/java.sun.com\/jsp\/jstl\/core&quot; %&gt; &lt;html&gt;   &lt;head&gt;     &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=ISO-8859-1&quot;&gt;     &lt;title&gt;Users List&lt;\/title&gt;     &lt;link href=&quot;&lt;c:url value='\/static\/css\/bootstrap.css' \/&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;\/link&gt;     &lt;link href=&quot;&lt;c:url value='\/static\/css\/app.css' \/&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;\/link&gt; &lt;\/head&gt;   &lt;body&gt;     &lt;div class=&quot;generic-container&quot;&gt;         &lt;div class=&quot;panel panel-default&quot;&gt;               &lt;!-- Default panel contents --&gt;             &lt;div class=&quot;panel-heading&quot;&gt;&lt;span class=&quot;lead&quot;&gt;List of Users &lt;\/span&gt;&lt;\/div&gt;             &lt;table class=&quot;table table-hover&quot;&gt;                 &lt;thead&gt;                     &lt;tr&gt;                         &lt;th&gt;Firstname&lt;\/th&gt;                         &lt;th&gt;Lastname&lt;\/th&gt;                         &lt;th&gt;Email&lt;\/th&gt;                         &lt;th&gt;SSO ID&lt;\/th&gt;                         &lt;th width=&quot;100&quot;&gt;&lt;\/th&gt;                         &lt;th width=&quot;100&quot;&gt;&lt;\/th&gt;                     &lt;\/tr&gt;                 &lt;\/thead&gt;                 &lt;tbody&gt;                 &lt;c:forEach items=&quot;${users}&quot; var=&quot;user&quot;&gt;                     &lt;tr&gt;                         &lt;td&gt;${user.firstName}&lt;\/td&gt;                         &lt;td&gt;${user.lastName}&lt;\/td&gt;                         &lt;td&gt;${user.email}&lt;\/td&gt;                         &lt;td&gt;${user.ssoId}&lt;\/td&gt;                         &lt;td&gt;&lt;a href=&quot;&lt;c:url value='\/edit-user-${user.ssoId}' \/&gt;&quot; class=&quot;btn btn-success    custom-width&quot;&gt;edit&lt;\/a&gt;&lt;\/td&gt;                         &lt;td&gt;&lt;a href=&quot;&lt;c:url value='\/delete-user-${user.ssoId}' \/&gt;&quot; class=&quot;btn btn-danger    custom-width&quot;&gt;delete&lt;\/a&gt;&lt;\/td&gt;                     &lt;\/tr&gt;                 &lt;\/c:forEach&gt;                 &lt;\/tbody&gt;             &lt;\/table&gt;         &lt;\/div&gt;         &lt;div class=&quot;well&quot;&gt;             &lt;a href=&quot;&lt;c:url value='\/newuser' \/&gt;&quot;&gt;Add New User&lt;\/a&gt;         &lt;\/div&gt;     &lt;\/div&gt; &lt;\/body&gt; &lt;\/html&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">registration.jsp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">&lt;%@ page language=&quot;java&quot; contentType=&quot;text\/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&gt; &lt;%@ taglib prefix=&quot;form&quot; uri=&quot;http:\/\/www.springframework.org\/tags\/form&quot;%&gt; &lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http:\/\/java.sun.com\/jsp\/jstl\/core&quot; %&gt;   &lt;html&gt;   &lt;head&gt;     &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=ISO-8859-1&quot;&gt;     &lt;title&gt;User Registration Form&lt;\/title&gt;     &lt;link href=&quot;&lt;c:url value='\/static\/css\/bootstrap.css' \/&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;\/link&gt;     &lt;link href=&quot;&lt;c:url value='\/static\/css\/app.css' \/&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;\/link&gt; &lt;\/head&gt;   &lt;body&gt;       &lt;div class=&quot;generic-container&quot;&gt;     &lt;div class=&quot;well lead&quot;&gt;User Registration Form&lt;\/div&gt;     &lt;form:form method=&quot;POST&quot; modelAttribute=&quot;user&quot; class=&quot;form-horizontal&quot;&gt;         &lt;form:input type=&quot;hidden&quot; path=&quot;id&quot; id=&quot;id&quot;\/&gt;                   &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-group col-md-12&quot;&gt;                 &lt;label class=&quot;col-md-3 control-lable&quot; for=&quot;firstName&quot;&gt;First Name&lt;\/label&gt;                 &lt;div class=&quot;col-md-7&quot;&gt;                     &lt;form:input type=&quot;text&quot; path=&quot;firstName&quot; id=&quot;firstName&quot; class=&quot;form-control input-sm&quot;\/&gt;                     &lt;div class=&quot;has-error&quot;&gt;                         &lt;form:errors path=&quot;firstName&quot; class=&quot;help-inline&quot;\/&gt;                     &lt;\/div&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;           &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-group col-md-12&quot;&gt;                 &lt;label class=&quot;col-md-3 control-lable&quot; for=&quot;lastName&quot;&gt;Last Name&lt;\/label&gt;                 &lt;div class=&quot;col-md-7&quot;&gt;                     &lt;form:input type=&quot;text&quot; path=&quot;lastName&quot; id=&quot;lastName&quot; class=&quot;form-control input-sm&quot; \/&gt;                     &lt;div class=&quot;has-error&quot;&gt;                         &lt;form:errors path=&quot;lastName&quot; class=&quot;help-inline&quot;\/&gt;                     &lt;\/div&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;           &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-group col-md-12&quot;&gt;                 &lt;label class=&quot;col-md-3 control-lable&quot; for=&quot;ssoId&quot;&gt;SSO ID&lt;\/label&gt;                 &lt;div class=&quot;col-md-7&quot;&gt;                     &lt;c:choose&gt;                         &lt;c:when test=&quot;${edit}&quot;&gt;                             &lt;form:input type=&quot;text&quot; path=&quot;ssoId&quot; id=&quot;ssoId&quot; class=&quot;form-control    input-sm&quot; disabled=&quot;true&quot;\/&gt;                         &lt;\/c:when&gt;                         &lt;c:otherwise&gt;                             &lt;form:input type=&quot;text&quot; path=&quot;ssoId&quot; id=&quot;ssoId&quot; class=&quot;form-control    input-sm&quot; \/&gt;                             &lt;div class=&quot;has-error&quot;&gt;                                 &lt;form:errors path=&quot;ssoId&quot; class=&quot;help-inline&quot;\/&gt;                             &lt;\/div&gt;                         &lt;\/c:otherwise&gt;                     &lt;\/c:choose&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;           &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-group col-md-12&quot;&gt;                 &lt;label class=&quot;col-md-3 control-lable&quot; for=&quot;password&quot;&gt;Password&lt;\/label&gt;                 &lt;div class=&quot;col-md-7&quot;&gt;                     &lt;form:input type=&quot;password&quot; path=&quot;password&quot; id=&quot;password&quot; class=&quot;form-control input-sm&quot;   \/&gt;                     &lt;div class=&quot;has-error&quot;&gt;                         &lt;form:errors path=&quot;password&quot; class=&quot;help-inline&quot;\/&gt;                     &lt;\/div&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;           &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-group col-md-12&quot;&gt;                 &lt;label class=&quot;col-md-3 control-lable&quot; for=&quot;email&quot;&gt;Email&lt;\/label&gt;                 &lt;div class=&quot;col-md-7&quot;&gt;                     &lt;form:input type=&quot;text&quot; path=&quot;email&quot; id=&quot;email&quot; class=&quot;form-control input-sm&quot; \/&gt;                     &lt;div class=&quot;has-error&quot;&gt;                         &lt;form:errors path=&quot;email&quot; class=&quot;help-inline&quot;\/&gt;                     &lt;\/div&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;           &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-group col-md-12&quot;&gt;                 &lt;label class=&quot;col-md-3 control-lable&quot; for=&quot;userProfiles&quot;&gt;Roles&lt;\/label&gt;                 &lt;div class=&quot;col-md-7&quot;&gt;                     &lt;form:select path=&quot;userProfiles&quot; items=&quot;${roles}&quot; multiple=&quot;true&quot; itemValue=&quot;id&quot;   itemLabel=&quot;type&quot; class=&quot;form-control input-sm&quot; \/&gt;                     &lt;div class=&quot;has-error&quot;&gt;                         &lt;form:errors path=&quot;userProfiles&quot; class=&quot;help-inline&quot;\/&gt;                     &lt;\/div&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;           &lt;div class=&quot;row&quot;&gt;             &lt;div class=&quot;form-actions floatRight&quot;&gt;                 &lt;c:choose&gt;                     &lt;c:when test=&quot;${edit}&quot;&gt;                         &lt;input type=&quot;submit&quot; value=&quot;Update&quot; class=&quot;btn btn-primary btn-sm&quot;\/&gt; or &lt;a   href=&quot;&lt;c:url value='\/list' \/&gt;&quot;&gt;Cancel&lt;\/a&gt;                     &lt;\/c:when&gt;                     &lt;c:otherwise&gt;                         &lt;input type=&quot;submit&quot; value=&quot;Register&quot; class=&quot;btn btn-primary btn-sm&quot;\/&gt; or &lt;a   href=&quot;&lt;c:url value='\/list' \/&gt;&quot;&gt;Cancel&lt;\/a&gt;                     &lt;\/c:otherwise&gt;                 &lt;\/c:choose&gt;             &lt;\/div&gt;         &lt;\/div&gt;     &lt;\/form:form&gt;     &lt;\/div&gt; &lt;\/body&gt; &lt;\/html&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">registrationsuccess.jsp<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">&lt;%@ page language=&quot;java&quot; contentType=&quot;text\/html; charset=ISO-8859-1&quot; pageEncoding=&quot;ISO-8859-1&quot;%&gt; &lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http:\/\/java.sun.com\/jsp\/jstl\/core&quot; %&gt;     &lt;html&gt; &lt;head&gt;     &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=ISO-8859-1&quot;&gt;     &lt;title&gt;Registration Confirmation Page&lt;\/title&gt;     &lt;link href=&quot;&lt;c:url value='\/static\/css\/bootstrap.css' \/&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;\/link&gt;     &lt;link href=&quot;&lt;c:url value='\/static\/css\/app.css' \/&gt;&quot; rel=&quot;stylesheet&quot;&gt;&lt;\/link&gt; &lt;\/head&gt; &lt;body&gt; &lt;div class=&quot;generic-container&quot;&gt;     &lt;div class=&quot;alert alert-success lead&quot;&gt;         ${success}     &lt;\/div&gt;           &lt;span class=&quot;well floatRight&quot;&gt;         Go to &lt;a href=&quot;&lt;c:url value='\/list' \/&gt;&quot;&gt;Users List&lt;\/a&gt;     &lt;\/span&gt; &lt;\/div&gt; &lt;\/body&gt;   &lt;\/html&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418 \u043a\u0440\u043e\u0448\u0435\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441\u0442\u0438\u043b\u0435\u0439: <\/p>\n<p>  <b><code>app.css<\/code><\/b><\/p>\n<pre><code class=\"css\">body, #mainWrapper {     height: 100%;     background-color:rgb(245, 245, 245); }   body, .form-control{     font-size:12px!important; }   .floatRight{     float:right;     margin-right: 18px; }   .has-error{     color:red; }   .generic-container {   position:fixed;   width:80%;   margin-left: 20px;   margin-top: 20px;   margin-bottom: 20px;   padding: 20px;   background-color: #EAE7E7;   border: 1px solid #ddd;   border-radius: 4px;   box-shadow: 0 0 30px black; }   .custom-width {     width: 80px !important; } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0428\u0430\u0433 12: \u0421\u043e\u0437\u0434\u0430\u0442\u044c, \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h4>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0447\u0435\u0440\u0435\u0437 IDE \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u043b\u0438 \u0436\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 .war \u0444\u0430\u0439\u043b. <\/p>\n<p>  \u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/108\/e8f\/0ce\/108e8f0cea1c405fa802a48b59a73d96.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u0435\u0437 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/bf4\/8bc\/17e\/bf48bc17e4be47c0b15488636820d81f.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/e79\/578\/ed5\/e79578ed57d449d8a8f21ae0443728ad.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/e79\/578\/ed5\/e79578ed57d449d8a8f21ae0443728ad.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<h4>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h4>\n<p>  \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Spring MVC \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 Hibernate.       <\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/271025\/\"> http:\/\/habrahabr.ru\/post\/271025\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0441\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0432 Hibernate, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446 \u0432 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 Spring 4 MVC. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u043c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u043c\u043d\u043e\u0433\u0438\u043c \u0432 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u0438 \u0432 \u0431\u044d\u043a-\u044d\u043d\u0434&#8217;\u0430\u0445. \u041c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0447\u0435\u0440\u0435\u0437 \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<p>  \u042d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>org.springframework.core.convert.converter.Converter<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043d\u0430\u043c \u0432 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 ID&#8217; \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0430\u0445 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/266\/a3f\/e38\/266a3fe3814a45a9bd4cc69fb035698c.png\"\/>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-268348","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/268348","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=268348"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/268348\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=268348"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=268348"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=268348"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}