JPA Crud repository query method not working - spring-data-jpa

I want to get a list of users by username, with enabled status and has phone number. I managed to get it working till I add the phone number parameter.
here is my code:
//crud repo
List<Users> findAllByUserNameContainsAndEnabledIsAndMobileNotNull(String userName, String enabled);
// controller
public Set<User> searchByName(#PathVariable String username) throws Exception {
Set<User> result = new HashSet<>();
result.addAll(userRepository.findAllByUserNameContainsAndEnabledIsAndMobileNotNull(username, "Y"));
return result;
}
// user class
public class User{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(precision = 18, scale = 0)
private BigDecimal id;
#Column(name = "Enabled", columnDefinition = "char(1) default 'Y'")
private String enabled;
private String username;
private String mobile;
// getters setters..

What is your phone number parameter called? You said it was working until that. The names have to match.
Here is all supported keywords in the method names:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

I have started new project and everything works as expected, so the problem is not in method name. Here is code I've tested:
Entity
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(precision = 18, scale = 0)
private BigDecimal id;
#Column(name = "Enabled", columnDefinition = "char(1) default 'Y'")
private String enabled;
private String userName;
private String mobile;
public User(String enabled, String userName, String mobile) {
this.enabled = enabled;
this.userName = userName;
this.mobile = mobile;
}
}
Repositiory
public interface UserRepository extends CrudRepository<User, BigDecimal> {
List<User> findAllByUserNameContainsAndEnabledIsAndMobileNotNull(String userName, String enabled);
}
Test
#SpringBootTest
#ExtendWith(SpringExtension.class)
#ActiveProfiles("test")
class UserRepositoryTest {
#Autowired
private UserRepository userRepository;
#Test
void test_findAllByUserNameContainsAndEnabledIsAndMobileNotNull() {
User user1 = new User("Y", "user1", "mobile");
User user2 = new User("Y", "user2", null);
userRepository.save(user1);
userRepository.save(user2);
List<User> all = userRepository.findAllByUserNameContainsAndEnabledIsAndMobileNotNull("user", "Y");
System.out.println("all = " + all);
}
}
And only one record in the output:
all = [User(id=1, enabled=Y, userName=user1, mobile=mobile)]

Related

How to add new records to a field with #OneToOne in spring Data?

I am making a jsf + spring application.
The database contains a table of games and it is displayed on one of the pages of the site.
Each game has a genre list and development status. These fields are annotated with #OneToMany and #OneToOne respectively and are also tables in the database.
But here's the question: How do I add new games now? How do I initialize these fields? Because the only way I see is to create a new genre for a new game every time. That is, even if game A and games B are of the same genre, then I have to create two different unique genres, not one.
And how to initialize these fields from JSF?
For example from the <p: selectOneMenu> tag
game.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "game")
public class Game
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "name")
private String name;
#Column(name = "budget")
private String budget;
#Column(name = "profit")
private String profit;
#Column(name = "number")
private String number;
#OneToOne(optional = false, cascade = CascadeType.REFRESH)
#JoinColumn(name = "platform")
private Platform platform;
#OneToOne(optional = false, cascade = CascadeType.REFRESH)
#JoinColumn(name = "status")
private Status status;
#Column(name = "start")
private Date start;
#Column(name = "end")
private Date end;
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(name = "game_genre",
joinColumns = #JoinColumn(name= "game_id"),
inverseJoinColumns = #JoinColumn(name= "genre_id"))
private List<Genre> listGenre;
public void update(Game new_game)
{
this.name = new_game.name;
this.budget = new_game.budget;
this.profit = new_game.profit;
this.number = new_game.number;
this.platform = new_game.platform;
this.status = new_game.status;
this.start = new_game.start;
this.end = new_game.end;
}
}
development status
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "status")
public class Status implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "Название")
private String Name;
#Column(name = "Описание")
private String description;
public void update(Status new_game)
{
this.description = new_game.description;
this.Name = new_game.Name;
}
}
genre:
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "genre")
public class Genre implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "description")
private String description;
public void update(Genre new_game)
{
this.name = new_game.name;
this.description = new_game.description;
}
}
Bean
#Component(value = "listgames")
#SessionScope
public class GamesView {
#Autowired
private GamesService gamesService;
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
private List<Game> All_games = new ArrayList<Game>();
private Game newGame=new Game();
public Game getNewGame() {
return newGame;
}
public void setNewGame(Game newGame) {
this.newGame = newGame;
}
public void onRowEdit(RowEditEvent event) {
Game new_game=(Game)event.getObject();
All_games.get(new_game.getId()-1).update(new_game);
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "INFO", "X/Y edit successful!");
FacesContext.getCurrentInstance().addMessage(null, msg);
int i=0;
i++;
}
public void createNew() {
gamesService.addBank(newGame);
newGame = new Game();
}
public List<Game> getAll_games() {
return gamesService.getAll();
}
public void setAll_games(List<Game> all_games) {
All_games = all_games;
}
}

Spring Boot : Building object Rest API

I created 4 classes for 3 tables. Those tables are built to store orders with products.
My first entity is orders :
#Entity
#Table(name="orders")
public class OrderEntity implements Serializable {
...
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
private UserEntity seller;
private String paymentMode;
private double totalAmount;
#OneToMany(mappedBy = "pk.order")
private List<OrderProductEntity> orderProducts;
#DateTimeFormat
private Date createdAt;
...
}
My second entity is products:
#Entity
#Table(name="products")
#Getter #Setter
public class ProductEntity implements Serializable {
...
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String productKeyId;
#ManyToOne
#JoinColumn(name = "category_id")
private CategoryEntity category;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private double price;
#Column(nullable = false)
private int availableQty;
#JsonManagedReference
#OneToMany(mappedBy = "pk.product", fetch = FetchType.EAGER)
#Valid
private List<OrderProductEntity> orderProducts;
...
}
I also define the pivot table in the OrderProductEntity:
#Entity
#Table(name="order_product")
#Getter #Setter
public class OrderProductEntity {
#EmbeddedId
#JsonIgnore
private OrderProductPK pk;
#Column(nullable = false)
private Integer quantity;
// default constructor
public OrderProductEntity(){}
public OrderProductEntity(OrderEntity order, ProductEntity product, Integer quantity) {
pk = new OrderProductPK();
pk.setOrder(order);
pk.setProduct(product);
this.quantity = quantity;
}
}
And I defined the PK of this table :
#Embeddable
#Getter #Setter
public class OrderProductPK implements Serializable {
#JsonBackReference
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "order_id")
private OrderEntity order;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "product_id")
private ProductEntity product;
}
Now my issue is to return the data to the front office by a web service Rest.
I created a model that represent what i want to obtain as result.
public class OrderRest {
private String orderKeyId;
private String paymentMode;
private double totalAmount;
private List<ProductRest> orderProducts;
private UserRest seller;
private Date createdAt;
}
And :
public class ProductRest {
private String productKeyId;
private String name;
private double price;
private int qty;
private String imgPath;
private CategoryRest category;
}
In my controller i want to return an OrderRest object :
public List<OrderRest> getOrders() {
List<OrderRest> returnValue = new ArrayList<>();
List<OrderDto> orderDtos = orderService.getOrders();
// loop the result
for (OrderDto orderDto : orderDtos) {
OrderRest orderRest = new OrderRest();
ModelMapper modelMapper = new ModelMapper();
orderRest = modelMapper.map(orderDto, OrderRest.class);
returnValue.add(orderRest);
}
return returnValue;
}
THis method map the List of OrderRest and call the service layer :
public List<OrderDto> getOrders() {
List<OrderDto> returnValue = new ArrayList<>();
Iterable<OrderEntity> orderEntities = orderRepository.findAll();
ModelMapper modelMapper = new ModelMapper();
for(OrderEntity orderEntity: orderEntities) {
OrderDto orderDto = new OrderDto();
UserDto userDto = orderDto.getSeller();
List<OrderProductDto> orderProductDtos = orderDto.getOrderProducts();
orderDto = modelMapper.map(orderEntity, OrderDto.class);
returnValue.add(orderDto);
}
return returnValue;
}
With OrderDto :
public class OrderDto implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private Long id;
private String orderKeyId;
private String paymentMode;
private double totalAmount;
private List<OrderProductDto> orderProducts;
private UserDto seller;
private Date createdAt;
}
And OrderProductDto :
public class OrderProductDto implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private String productKeyId;
private String name;
private Integer price;
private Integer qty;
private String imgPath;
private CategoryDto category;
}
My issue is concerning what i return from the REST API :
my product list returns nothing :
"orderProducts": [
{
"productKeyId": null,
"name": null,
"price": 0.0,
"qty": 0,
"imgPath": null,
"category": null
},...
]

How to find the specified field in spring-data-jpa

I want to find the specified field with the interface which extends JpaSpecificationExecutor.but i have not idea.
for example,i just need to find id,nickname in the user entity,what shall I do?
#Service
public class UserService {
public Page<User> findAll(User user, Pageable pageable) {
List<Predicate> predicates = new ArrayList<>();
if (user != null) {
//some condition
}
query.where(predicates.toArray(new Predicate[predicates.size()]));
return query.getRestriction();
}
}
#Repository
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
#Data
#Entity
#Table(name = "sys_user")
public class Note implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true)
private String email;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String nickname;
}
Here is answer on your question: https://www.baeldung.com/spring-data-jpa-projections .

Jpa Auditing dont save data in table auditing

I have to implementes Auditing in my aplication.. i inserting this data correctly
but i want to save all atributter from my Entity ,
Exemple, name, epigrafe, .. and olthers.
I implemented the mothod but dosent work, just dont save the atributte..
lets see..
#Entity
#EntityListeners(AuditingEntityListener.class)
#Table(name = "logradouros_historico", schema = "aud")
public class LogradourosHistorico {
#Id
#GeneratedValue
private Long id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id_logradouro")
private Logradouros logradouro;
#CreatedBy
private String modificadoPor;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedDate = new Date();
#Enumerated(EnumType.STRING)
private Acoes acao;
#Column(name = "nome")
private String nome; //nome do logradouro
public LogradourosHistorico() {
super();
}
public LogradourosHistorico(Logradouros logradouro, String modificadoPor,
Acoes acao) {
super();
this.logradouro = logradouro;
this.modificadoPor = modificadoPor;
this.acao = acao;
}
//getters and setters
my class entityListner
public class LogradourosEntityListener {
#PostPersist
public void prePersist(Logradouros target) {
perform(target, Acoes.INSERTED);
}
#PreUpdate
public void preUpdate(Logradouros target) {
perform(target, Acoes.UPDATED);
}
#PreRemove
public void preRemove(Logradouros target) {
perform(target, Acoes.DELETED);
}
#Transactional()
private void perform(Logradouros target, Acoes acao) {
target.getNome();
EntityManager entityManager = BeanUtil.getBean(EntityManager.class);
entityManager.persist(new LogradourosHistorico(target, acao));
}
}
my class Logradouros
#Entity
#EntityListeners(LogradourosEntityListener.class)
#Table(name = "logradouros", schema = "glb", uniqueConstraints= #UniqueConstraint(columnNames={"id_entidade", "idLogradouro"}))
public class Logradouros extends Auditable<String> implements Serializable {
private static final long serialVersionUID = 3703309412387185484L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int idLogradouro;
#Column(name = "cep_geral")
private String cepGeral;
#Column(name = "epigrafe")
private String epigrafe;
#NotNull
#Column(name = "nome")
private String nome;
#Column(name = "nome_exibicao")
private String nomeExibicao;
#JoinColumn(name = "id_entidade")
#ManyToOne(/*cascade = CascadeType.ALL*/)
private Entidades entidade;
#NotNull
#JoinColumn(name = "id_municipio")
#ManyToOne(/*cascade = CascadeType.ALL*/)
private Municipios municipio;
// gettrs and settrs
so what i did wrong because i cant get the nome of entity Logradouros

Spring Data JPA Specification Manyto One relationship

I have two entities in Spring Data JPA:
User--->* TaxPayment
The goal is to get the all the taxpayments related to user_id:
User.java
public class User extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
..........
}
TaxPayment.jva
public class TaxPayment implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "payment_date", nullable = false)
private LocalDate paymentDate;
#NotNull
#Column(name = "amount", precision=10, scale=2, nullable = false)
private BigDecimal amount;
#Column(name = "reference")
private String reference;
#ManyToOne
private User user;
public Long getId() {
return id;
}..
}
I dont wan't to have oneTOMany Annotation from User.java and the column mapped in the Taxpayment as user_id.
Specification class as follows:
final class TaxPaymentSpecification {
private TaxPaymentSpecification(){
}
static Specification<TaxPayment> hasUser(Long userId){
return new Specification<TaxPayment>() {
#Override
public Predicate toPredicate(Root<TaxPayment> arg0, CriteriaQuery<?> arg1,
CriteriaBuilder arg2) {
// TODO Auto-generated method stub
Root<TaxPayment> root = arg0;
Subquery<Long> subqry = arg1.subquery(Long.class);
Root<User> user = subqry.from(User.class);
final Join<User,TaxPayment> taxpays = root.join("user");
subqry.select(taxpays.<Long> get("user_id"));
subqry.where(arg2.equal(user.<Long> get("id"),userId));
return arg2.in(arg0.get("user_id")).value(subqry);
}
};
}
}
Is specification is correct or wrong as per my goal to get all the TaxPayment related to user_id?
There is no need to use subquery if you already know the userId, which will be the value of user_id in TaxPayment table:
#Override
public Predicate toPredicate(Root<TaxPayment> arg0, CriteriaQuery<?> arg1,
CriteriaBuilder arg2) {
return arg2.equal(arg0.get("user_id"), userId);
}