[BAEL-1686] - Update project after editor's article review

This commit is contained in:
Jorge Collado 2018-05-22 18:20:10 +02:00 committed by José Carlos Valero Sánchez
parent f8b9555e42
commit 2b08d2c7ce
9 changed files with 81 additions and 205 deletions

View File

@ -1,10 +1,8 @@
package com.baeldung; package com.baeldung;
import com.baeldung.controller.repository.AddressAvailabilityRepository;
import com.baeldung.controller.repository.AddressRepository; import com.baeldung.controller.repository.AddressRepository;
import com.baeldung.controller.repository.UserRepository; import com.baeldung.controller.repository.UserRepository;
import com.baeldung.entity.Address; import com.baeldung.entity.Address;
import com.baeldung.entity.AddressAvailability;
import com.baeldung.entity.User; import com.baeldung.entity.User;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -15,31 +13,32 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@SpringBootApplication @EntityScan("com.baeldung.entity") @EnableJpaRepositories("com.baeldung.controller.repository") @SpringBootApplication
@EnableAutoConfiguration public class Application { @EntityScan("com.baeldung.entity")
@EnableJpaRepositories("com.baeldung.controller.repository")
@EnableAutoConfiguration
public class Application {
@Autowired private UserRepository personRepository; @Autowired
@Autowired private AddressRepository addressRepository; private UserRepository personRepository;
@Autowired private AddressAvailabilityRepository addressAvailabilityRepository; @Autowired
private AddressRepository addressRepository;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(Application.class, args); SpringApplication.run(Application.class, args);
} }
@PostConstruct private void initializeData() { @PostConstruct
private void initializeData() {
// Create John // Create John
final AddressAvailability addressOneAvailability = new AddressAvailability(true, true, false, false, false, true, true);
addressAvailabilityRepository.save(addressOneAvailability);
final User john = new User("John"); final User john = new User("John");
personRepository.save(john); personRepository.save(john);
final Address addressOne = new Address("Fake Street 1", "Fake Country", addressOneAvailability, john); final Address addressOne = new Address("Fake Street 1", "Spain", john);
addressRepository.save(addressOne); addressRepository.save(addressOne);
// Create Lisa // Create Lisa
final AddressAvailability addressTwoAvailability = new AddressAvailability(false, false, false, false, false, true, true);
addressAvailabilityRepository.save(addressTwoAvailability);
final User lisa = new User("Lisa"); final User lisa = new User("Lisa");
personRepository.save(lisa); personRepository.save(lisa);
final Address addressTwo = new Address("Real Street 1", "Real Country", addressTwoAvailability, lisa); final Address addressTwo = new Address("Real Street 1", "Germany", lisa);
addressRepository.save(addressTwo); addressRepository.save(addressTwo);
} }
} }

View File

@ -1,10 +1,8 @@
package com.baeldung.controller; package com.baeldung.controller;
import com.baeldung.controller.repository.AddressAvailabilityRepository;
import com.baeldung.controller.repository.AddressRepository; import com.baeldung.controller.repository.AddressRepository;
import com.baeldung.controller.repository.UserRepository; import com.baeldung.controller.repository.UserRepository;
import com.baeldung.entity.Address; import com.baeldung.entity.Address;
import com.baeldung.entity.AddressAvailability;
import com.baeldung.entity.User; import com.baeldung.entity.User;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
@ -14,11 +12,13 @@ import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController public class QueryController { @RestController
public class QueryController {
@Autowired private UserRepository personRepository; @Autowired
@Autowired private AddressRepository addressRepository; private UserRepository personRepository;
@Autowired private AddressAvailabilityRepository addressAvailabilityRepository; @Autowired
private AddressRepository addressRepository;
@GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<User> queryOverUser(@QuerydslPredicate(root = User.class) Predicate predicate) { public Iterable<User> queryOverUser(@QuerydslPredicate(root = User.class) Predicate predicate) {
@ -31,11 +31,4 @@ import org.springframework.web.bind.annotation.RestController;
final BooleanBuilder builder = new BooleanBuilder(); final BooleanBuilder builder = new BooleanBuilder();
return addressRepository.findAll(builder.and(predicate)); return addressRepository.findAll(builder.and(predicate));
} }
@GetMapping(value = "/addressAvailabilities", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<AddressAvailability> queryOverAddressAvailability(
@QuerydslPredicate(root = AddressAvailability.class) Predicate predicate) {
final BooleanBuilder builder = new BooleanBuilder();
return addressAvailabilityRepository.findAll(builder.and(predicate));
}
} }

View File

@ -1,19 +0,0 @@
package com.baeldung.controller.repository;
import com.baeldung.entity.AddressAvailability;
import com.baeldung.entity.QAddressAvailability;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.core.types.dsl.StringPath;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.querydsl.binding.SingleValueBinding;
public interface AddressAvailabilityRepository
extends JpaRepository<AddressAvailability, Long>, QueryDslPredicateExecutor<AddressAvailability>,
QuerydslBinderCustomizer<QAddressAvailability> {
@Override default void customize(final QuerydslBindings bindings, final QAddressAvailability root) {
bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::eq);
}
}

View File

@ -12,7 +12,8 @@ import org.springframework.data.querydsl.binding.SingleValueBinding;
public interface AddressRepository public interface AddressRepository
extends JpaRepository<Address, Long>, QueryDslPredicateExecutor<Address>, QuerydslBinderCustomizer<QAddress> { extends JpaRepository<Address, Long>, QueryDslPredicateExecutor<Address>, QuerydslBinderCustomizer<QAddress> {
@Override default void customize(final QuerydslBindings bindings, final QAddress root) { @Override
default void customize(final QuerydslBindings bindings, final QAddress root) {
bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::eq); bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::eq);
} }
} }

View File

@ -12,7 +12,8 @@ import org.springframework.data.querydsl.binding.SingleValueBinding;
public interface UserRepository public interface UserRepository
extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User>, QuerydslBinderCustomizer<QUser> { extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User>, QuerydslBinderCustomizer<QUser> {
@Override default void customize(final QuerydslBindings bindings, final QUser root) { @Override
default void customize(final QuerydslBindings bindings, final QUser root) {
bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::eq); bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::eq);
} }
} }

View File

@ -1,28 +1,33 @@
package com.baeldung.entity; package com.baeldung.entity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*; import javax.persistence.*;
@Entity @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class Address { @Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Address {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false) private Long id; @Id
@Column private String address; @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column private String country; @Column(name = "id", unique = true, nullable = false)
@OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "address_id") @JsonBackReference private AddressAvailability private Long id;
addressAvailability; @Column
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") @JsonBackReference private User user; private String address;
@Column
private String country;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public Address() { public Address() {
} }
public Address(String address, String country, AddressAvailability addressAvailability, User user) { public Address(String address, String country, User user) {
this.id = id; this.id = id;
this.address = address; this.address = address;
this.country = country; this.country = country;
this.addressAvailability = addressAvailability;
this.user = user; this.user = user;
} }
@ -49,12 +54,4 @@ import javax.persistence.*;
public void setCountry(String country) { public void setCountry(String country) {
this.country = country; this.country = country;
} }
public AddressAvailability getAddressAvailability() {
return addressAvailability;
}
public void setAddressAvailability(AddressAvailability addressAvailability) {
this.addressAvailability = addressAvailability;
}
} }

View File

@ -1,114 +0,0 @@
package com.baeldung.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
@Table(name = "address_availability") @Entity @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class AddressAvailability {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false) private Long id;
@Column private Boolean monday;
@Column private Boolean tuesday;
@Column private Boolean wednesday;
@Column private Boolean thursday;
@Column private Boolean friday;
@Column private Boolean saturday;
@Column private Boolean sunday;
@OneToOne(mappedBy = "addressAvailability") @JsonManagedReference private Address address;
public AddressAvailability() {
}
public AddressAvailability(Boolean monday, Boolean tuesday, Boolean wednesday, Boolean thursday, Boolean friday,
Boolean saturday, Boolean sunday) {
this.monday = monday;
this.tuesday = tuesday;
this.wednesday = wednesday;
this.thursday = thursday;
this.friday = friday;
this.saturday = saturday;
this.sunday = sunday;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Boolean getMonday() {
return monday;
}
public void setMonday(Boolean monday) {
this.monday = monday;
}
public Boolean getTuesday() {
return tuesday;
}
public void setTuesday(Boolean tuesday) {
this.tuesday = tuesday;
}
public Boolean getWednesday() {
return wednesday;
}
public void setWednesday(Boolean wednesday) {
this.wednesday = wednesday;
}
public Boolean getThursday() {
return thursday;
}
public void setThursday(Boolean thursday) {
this.thursday = thursday;
}
public Boolean getFriday() {
return friday;
}
public void setFriday(Boolean friday) {
this.friday = friday;
}
public Boolean getSaturday() {
return saturday;
}
public void setSaturday(Boolean saturday) {
this.saturday = saturday;
}
public Boolean getSunday() {
return sunday;
}
public void setSunday(Boolean sunday) {
this.sunday = sunday;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

View File

@ -1,17 +1,22 @@
package com.baeldung.entity; package com.baeldung.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*; import javax.persistence.*;
import java.util.List;
@Entity @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) public class User { @Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false) private Long id; @Id
@Column private String name; @GeneratedValue(strategy = GenerationType.IDENTITY)
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user") @JsonManagedReference private List<Address> addresses; @Column(name = "id", unique = true, nullable = false)
private Long id;
@Column
private String name;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
private Address address;
public User() { public User() {
} }
@ -36,11 +41,11 @@ import java.util.List;
this.name = name; this.name = name;
} }
public List<Address> getAddresses() { public Address getAddress() {
return addresses; return address;
} }
public void setAddresses(List<Address> addresses) { public void setAddress(Address address) {
this.addresses = addresses; this.address = address;
} }
} }

View File

@ -20,33 +20,46 @@ import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) @WebAppConfiguration @RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
public class QuerydslIntegrationTest { public class QuerydslIntegrationTest {
final MediaType contentType = final MediaType contentType =
new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
@Autowired private WebApplicationContext webApplicationContext; @Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc; private MockMvc mockMvc;
@Before public void setupMockMvc() { @Before
public void setupMockMvc() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
} }
@Test public void givenRequestHasBeenMade_whenQueryAddressFilteringByUserName_thenGetJohn() throws Exception { @Test
mockMvc.perform(get("/addresses?user.name=John")).andExpect(status().isOk()).andExpect(content().contentType(contentType)) public void givenRequest_whenQueryUserFilteringByCountrySpain_thenGetJohn() throws Exception {
.andExpect(jsonPath("$", hasSize(1))).andExpect(jsonPath("$[0].address", is("Fake Street 1"))) mockMvc.perform(get("/users?address.country=Spain")).andExpect(status().isOk()).andExpect(content()
.andExpect(jsonPath("$[0].country", is("Fake Country"))); .contentType
(contentType))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].name", is("John")))
.andExpect(jsonPath("$[0].address.address", is("Fake Street 1")))
.andExpect(jsonPath("$[0].address.country", is("Spain")));
} }
@Test public void givenRequestHasBeenMade_whenQueryOverAddressAvailabilityFilteringByAddressCountry_thenGetAvailability() @Test
throws Exception { public void givenRequest_whenQueryUserWithoutFilter_thenGetJohnAndLisa() throws Exception {
mockMvc.perform(get("/addressAvailabilities?address.country=Real Country")).andExpect(status().isOk()) mockMvc.perform(get("/users")).andExpect(status().isOk()).andExpect(content()
.andExpect(content().contentType(contentType)).andExpect(jsonPath("$", hasSize(1))) .contentType
.andExpect(jsonPath("$[0].monday", is(false))).andExpect(jsonPath("$[0].tuesday", is(false))) (contentType))
.andExpect(jsonPath("$[0].wednesday", is(false))).andExpect(jsonPath("$[0].thursday", is(false))) .andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].friday", is(false))).andExpect(jsonPath("$[0].saturday", is(true))) .andExpect(jsonPath("$[0].name", is("John")))
.andExpect(jsonPath("$[0].sunday", is(true))); .andExpect(jsonPath("$[0].address.address", is("Fake Street 1")))
.andExpect(jsonPath("$[0].address.country", is("Spain")))
.andExpect(jsonPath("$[1].name", is("Lisa")))
.andExpect(jsonPath("$[1].address.address", is("Real Street 1")))
.andExpect(jsonPath("$[1].address.country", is("Germany")));
} }
} }