From 701dcb2593a528b6f4c899144075d289e5b298a2 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Fri, 1 Jul 2016 22:58:59 +0200 Subject: [PATCH] More JPA stuff --- SpringJava/JPA/context.xml | 53 ++++++++++ SpringJava/JPA/pom.xml | 16 +-- .../de/spring/persistence/example/domain/Ad.java | 108 ++++++++++----------- .../persistence/example/domain/AdDescription.java | 100 +++++++++++++++++++ .../repository/AdDescriptionRepository.java | 13 +++ .../example/repository/AdRepository.java | 13 ++- .../de/spring/rest/controllers/AdController.java | 10 +- .../datasource-configuration.xml | 33 ++----- .../spring-configuration/jpa-configuration.xml | 4 +- SpringJava/JPA/src/main/webapp/WEB-INF/web.xml | 20 ++++ 10 files changed, 278 insertions(+), 92 deletions(-) create mode 100644 SpringJava/JPA/context.xml create mode 100644 SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/AdDescription.java create mode 100644 SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdDescriptionRepository.java diff --git a/SpringJava/JPA/context.xml b/SpringJava/JPA/context.xml new file mode 100644 index 0000000..e053ee3 --- /dev/null +++ b/SpringJava/JPA/context.xml @@ -0,0 +1,53 @@ + + + + + + + WEB-INF/web.xml + + + + + + + + + + + + + diff --git a/SpringJava/JPA/pom.xml b/SpringJava/JPA/pom.xml index c8a763a..1c800b3 100644 --- a/SpringJava/JPA/pom.xml +++ b/SpringJava/JPA/pom.xml @@ -13,8 +13,8 @@ https://gumartinm.name/ - scm:git:http://git.gumartinm.name/Spring/JPA - http://git.gumartinm.name/Spring/JPA + scm:git:https://git.gumartinm.name/Spring/JPA + https://git.gumartinm.name/Spring/JPA @@ -104,18 +104,18 @@ + + javax.inject + javax.inject + 1 + cglib cglib 2.2.2 - - - com.mchange - c3p0 - 0.9.5.2 - + diff --git a/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/Ad.java b/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/Ad.java index e29ec68..6784538 100644 --- a/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/Ad.java +++ b/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/Ad.java @@ -2,43 +2,88 @@ package de.spring.persistence.example.domain; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.Set; import javax.persistence.Column; +import javax.persistence.Convert; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.NamedNativeQueries; +import javax.persistence.NamedNativeQuery; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.Max; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import de.spring.persistence.converters.LocalDateTimeAttributeConverter; + @Entity -@Table(schema = "mybatis_example") +@Table(name="ad", schema="mybatis_example") +// 1. Named query is JPL. It is portable. +// 2. Instead of annotating the domain class we should be using @Query annotation at the query method +// because it should be cleaner :) +// So you'd better use @Query. +//http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query +//See: de.spring.persistence.example.repository.AdRepository +@NamedQueries( + { + @NamedQuery( + name="Ad.findByIdQuery", + query="select a FROM AD a WHERE a.id = :id") + } + +) +// 1. Native query IS NOT JPL. It is not portable and it is written directly in the native language +// of the store. We can use special features at the cost of portability. +// 2. Instead of annotating the domain class we should be using @Query annotation at the query method +// because it should be cleaner :) +// So you'd better use @Query. +// http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query +// See: de.spring.persistence.example.repository.AdRepository +@NamedNativeQueries( + { + @NamedNativeQuery( + name="Ad.findByIdNativeQuery", + query="SELECT * FROM AD WHERE AD.ID = :id", + resultClass=Ad.class) + } +) public class Ad implements Serializable { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name = "id", updatable = false, nullable = false) + @Column(name="id", updatable=false, nullable=false) private Long id; + @OneToMany(mappedBy="ad", fetch=FetchType.LAZY, targetEntity=AdDescription.class) + private Set adDescriptions; + @Max(60) + @Column(name="company_id") private Long companyId; @Max(40) - @Column + @Column(name="company_categ_id") private Long companyCategId; - @Size(min=2, max=240) - @Column + @Size(min=2, max=255) + @Column(name="ad_mobile_image") private String adMobileImage; @NotNull - @Column(nullable = false) + @Convert(converter=LocalDateTimeAttributeConverter.class) + @Column(name="created_at", nullable=false) private LocalDateTime createdAt; @NotNull - @Column(nullable = false) + @Convert(converter=LocalDateTimeAttributeConverter.class) + @Column(name="updated_at", nullable = false) private LocalDateTime updatedAt; // It will be used by JPA when filling the property fields with data coming from data base. @@ -79,53 +124,4 @@ public class Ad implements Serializable { public LocalDateTime getUpdatedAt() { return updatedAt; } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((adMobileImage == null) ? 0 : adMobileImage.hashCode()); - result = prime * result + ((companyCategId == null) ? 0 : companyCategId.hashCode()); - result = prime * result + ((companyId == null) ? 0 : companyId.hashCode()); - result = prime * result + ((createdAt == null) ? 0 : createdAt.hashCode()); - result = prime * result + ((updatedAt == null) ? 0 : updatedAt.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Ad other = (Ad) obj; - if (adMobileImage == null) { - if (other.adMobileImage != null) - return false; - } else if (!adMobileImage.equals(other.adMobileImage)) - return false; - if (companyCategId == null) { - if (other.companyCategId != null) - return false; - } else if (!companyCategId.equals(other.companyCategId)) - return false; - if (companyId == null) { - if (other.companyId != null) - return false; - } else if (!companyId.equals(other.companyId)) - return false; - if (createdAt == null) { - if (other.createdAt != null) - return false; - } else if (!createdAt.equals(other.createdAt)) - return false; - if (updatedAt == null) { - if (other.updatedAt != null) - return false; - } else if (!updatedAt.equals(other.updatedAt)) - return false; - return true; - } } diff --git a/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/AdDescription.java b/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/AdDescription.java new file mode 100644 index 0000000..a3b7d16 --- /dev/null +++ b/SpringJava/JPA/src/main/java/de/spring/persistence/example/domain/AdDescription.java @@ -0,0 +1,100 @@ +package de.spring.persistence.example.domain; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.Max; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@Entity +@Table(name="ad_description", schema="mybatis_example") +public class AdDescription implements Serializable { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id", updatable=false, nullable=false) + private Long id; + + @NotNull + @ManyToOne(optional=false) + @JoinColumn(name="ad_id", referencedColumnName="id") + private Ad ad; + + @NotNull + @Max(60) + @Column(name="language_id") + private Long languageId; + + @NotNull + @Size(min=2, max=255) + @Column(name="ad_name") + private String adName; + + @NotNull + @Size(min=2, max=255) + @Column(name="ad_description") + private String adDescription; + + @NotNull + @Size(min=2, max=500) + @Column(name="ad_mobile_text") + private String adMobileText; + + @NotNull + @Size(min=2, max=3000) + @Column(name="ad_link") + private String adLink; + + // It will be used by JPA when filling the property fields with data coming from data base. + protected AdDescription() { + + } + + // It will be used by my code (for example by Unit Tests) + public AdDescription(Long id, Ad ad, Long languageId, String adName, String adDescription, + String adMobileText, String adLink) { + this.id = id; + this.languageId = languageId; + this.ad = ad; + this.adName = adName; + this.adDescription = adDescription; + this.adMobileText = adMobileText; + this.adLink = adLink; + } + + public Long getId() { + return id; + } + + public Ad getAd() { + return ad; + } + + public Long getLanguageId() { + return languageId; + } + + public String getAdName() { + return adName; + } + + public String getAdDescription() { + return adDescription; + } + + public String getAdMobileText() { + return adMobileText; + } + + public String getAdLink() { + return adLink; + } +} diff --git a/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdDescriptionRepository.java b/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdDescriptionRepository.java new file mode 100644 index 0000000..120b2c8 --- /dev/null +++ b/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdDescriptionRepository.java @@ -0,0 +1,13 @@ +package de.spring.persistence.example.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.repository.PagingAndSortingRepository; + +import de.spring.persistence.example.domain.Ad; +import de.spring.persistence.example.domain.AdDescription; + +public interface AdDescriptionRepository extends PagingAndSortingRepository { + + // Custom Query method + Page findByAd(Ad ad); +} diff --git a/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdRepository.java b/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdRepository.java index 8230c43..b625fed 100644 --- a/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdRepository.java +++ b/SpringJava/JPA/src/main/java/de/spring/persistence/example/repository/AdRepository.java @@ -1,9 +1,20 @@ package de.spring.persistence.example.repository; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; import de.spring.persistence.example.domain.Ad; public interface AdRepository extends PagingAndSortingRepository { - + + // Named Native Query (using the native language of the store) It is not portable. + // See de.spring.persistence.example.domain.Ad + @Query(value="SELECT * FROM AD WHERE AD.ID = :id", nativeQuery=true) + Ad findByIdNativeQuery(@Param("id") Long id); + + // Named Query (using JPL) It is portable. + // See de.spring.persistence.example.domain.Ad + @Query("SELECT * FROM AD WHERE AD.ID = :id") + Ad findByIdQuery(@Param("id") Long id); } diff --git a/SpringJava/JPA/src/main/java/de/spring/rest/controllers/AdController.java b/SpringJava/JPA/src/main/java/de/spring/rest/controllers/AdController.java index 16a61f9..ae0e29f 100644 --- a/SpringJava/JPA/src/main/java/de/spring/rest/controllers/AdController.java +++ b/SpringJava/JPA/src/main/java/de/spring/rest/controllers/AdController.java @@ -1,5 +1,7 @@ package de.spring.rest.controllers; +import javax.inject.Inject; + import org.resthub.web.controller.RepositoryBasedRestController; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -9,7 +11,13 @@ import de.spring.persistence.example.repository.AdRepository; @RestController @RequestMapping("/ads/") -public class AdController extends RepositoryBasedRestController{ +public class AdController extends RepositoryBasedRestController { + @Override + @Inject + public void setRepository(AdRepository repository) { + this.repository = repository; + } + // I do not have to do anything here because all I need is implemented by RepositoryBasedRestController :) } diff --git a/SpringJava/JPA/src/main/resources/spring-configuration/datasource-configuration.xml b/SpringJava/JPA/src/main/resources/spring-configuration/datasource-configuration.xml index 0951744..babff20 100644 --- a/SpringJava/JPA/src/main/resources/spring-configuration/datasource-configuration.xml +++ b/SpringJava/JPA/src/main/resources/spring-configuration/datasource-configuration.xml @@ -3,42 +3,27 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/tx - http://www.springframework.org/schema/tx/spring-tx.xsd"> + http://www.springframework.org/schema/tx/spring-tx.xsd + http://www.springframework.org/schema/jee + http://www.springframework.org/schema/jee/spring-jee.xsd"> - - - - - - - - - - - - - - - + + + + - + diff --git a/SpringJava/JPA/src/main/resources/spring-configuration/jpa-configuration.xml b/SpringJava/JPA/src/main/resources/spring-configuration/jpa-configuration.xml index 286d067..1a16615 100644 --- a/SpringJava/JPA/src/main/resources/spring-configuration/jpa-configuration.xml +++ b/SpringJava/JPA/src/main/resources/spring-configuration/jpa-configuration.xml @@ -19,7 +19,7 @@ - @@ -31,7 +31,7 @@ - diff --git a/SpringJava/JPA/src/main/webapp/WEB-INF/web.xml b/SpringJava/JPA/src/main/webapp/WEB-INF/web.xml index 01de2a8..31173b6 100644 --- a/SpringJava/JPA/src/main/webapp/WEB-INF/web.xml +++ b/SpringJava/JPA/src/main/webapp/WEB-INF/web.xml @@ -37,5 +37,25 @@ /* + + + + + OpenEntityManagerInViewFilter + org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter + + + OpenEntityManagerInViewFilter + /* + + -- 2.1.4