CrudRepository query with parameter - java

I would like to know if there is any way to use a parameter from a function I pass to a repository can be used in the #Query.
I would like to sort users by gaming platform so I added the following function to my UserRepository:
#Repository
public interface UserRepository extends CrudRepository<DbUser, Integer> {
#Query("SELECT * from users WHERE platform = *****parameter here***** ")
public List<DbUser> findAllByPlatform(String platform);
}
Does anybody know if this is possible? If so, how? If not, is there a clean workaround? Thanks in advance.
EDIT: My DbUser class:
#Entity
#Table(name = "users")
public class DbUser {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="user_id")
private int UserId;
#Column(name="user_name")
private String UserName;
#Column(name="email_address")
private String EmailAddress;
#Column(name="password_hash")
private int PasswordHash;
#Column(name="platform")
private String Platform;
#Column(name="platformid")
private String PlatformID;
#Convert(converter = StringListConvertor.class)
private ArrayList<String> Wishlist;
public DbUser(String userName, String emailAddress, int passwordHash, String platform, String platformID, String newWishlistItem){
UserName = userName;
EmailAddress = emailAddress;
PasswordHash = passwordHash;
Platform = platform;
PlatformID = platformID;
Wishlist.add(newWishlistItem);
}
public DbUser() {
}
public int getUserId() {
return UserId;
}
public void setUserId(int userId) {
UserId = userId;
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getEmailAddress() {
return EmailAddress;
}
public void setEmailAddress(String emailAddress) {
EmailAddress = emailAddress;
}
public int getPasswordHash() {
return PasswordHash;
}
public void setPasswordHash(int passwordHash) {
PasswordHash = passwordHash;
}
public String getPlatform() {
return Platform;
}
public void setPlatform(String platform) {
Platform = platform;
}
public String getPlatformID() {
return PlatformID;
}
public void setPlatformID(String platformID) {
PlatformID = platformID;
}
public ArrayList<String> getWishlist() {
return Wishlist;
}
public void setWishlist(ArrayList<String> wishlist) {
Wishlist = wishlist;
}
}

If you're using Spring data, annotate parameter with #Param and supply variable name to be used in query:
#Query("SELECT * from users WHERE platform = :pltfrm")
public List<DbUser> findAllByPlatform(#Param("pltfrm") String platform);

You can do something like that
#Query("SELECT * from users WHERE platform = %?1")
spring data jpa documentation

Related

How to check the user's verification code?

I am very new to Spring Boot. This is what I want to do: The user's email is test#example.com. That user already exists in my database, but I would like to know if their verificationCode is 123.
Entity:
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String email;
private String password;
private String verificationCode;
#Column(name = "verified", columnDefinition = "default false")
private boolean verified = false;
#CreationTimestamp
private Date registrationDate;
protected Users() {}
public Users(String email, String password, String verificationCode) {
this.email = email;
this.password = password;
this.verificationCode = verificationCode;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getVerificationCode() {
return verificationCode;
}
public void setVerificationCode(String verificationCode) {
this.verificationCode = verificationCode;
}
public boolean isVerified() {
return verified;
}
public void setVerified(boolean verified) {
this.verified = verified;
}
}
So with userRepository.findByEmail("test#example.com") I am getting the correct user, but how do I check their verification code?
if you're using userRepository.findByEmail("test#example.com"), just take the verification code from entity.
private static final String CODE = "123";
final User user = userRepository.findByEmail("test#example.com");
if (CODE.equals(user.getVerificationCode())) {
// do something
}
Another option to have it within query.
userRepository.findByEmailAndVerificationCode("test#example.com", CODE);
Or you can have something similar as Philipp wrote, but I would not get whole entity just find out if it exist. So solution would be
if (userRepository.existsByCode(CODE)) {
// do something
}
You search for something like that:
public void checkVerificationCode(final String verificationCode) {
final User user = userRepository.findByEmail("test#example.com");
if (!user.getVerificationCode(verificationCode)) {
throw new VerificationCodeException("Incorrect verification code.");
}
}

Hibernate can't create a table with #ManyToOne relation

I created a table of "User" which is perfectly created by hibernate, no problem on this one. The problem is on my second model (an entity called "Character") which is a model with a #ManyToOne relation, I don't know why but hibernate can't create this second table.
My server is a MySql instance with AWS RDS. The first table is created by hibernate but not the second.
#Entity
public class Character {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#ManyToOne
private User joueur;
private String pseudo;
private Integer points;
public Character() {
super();
}
public Character(User joueur) {
// appel a l'autre constructeur
this(joueur, null, null);
}
public Character(User joueur, String pseudo,Integer points) {
super();
this.joueur = joueur;
this.pseudo = pseudo;
this.points = points;
}
public Integer getId() {
return id;
}
public String getPseudo() {
return pseudo;
}
public void setPseudo(String pseudo) {
this.pseudo = pseudo;
}
public Integer getPoints() {
return points;
}
public void setPoints(Integer points) {
this.points = points;
}
public User getJoueur() {
return joueur;
}
}
#Entity // This tells Hibernate to make a table out of this class
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String username;
private String password;
#OneToMany(mappedBy = "joueur")
#OrderBy("id ASC")
private List<Character> personnages;
private String league;
private Integer points;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Character> getPersonnages() {
return personnages;
}
public void setPersonnages(List<Character> personnages) {
this.personnages = personnages;
}
public String getLeague() {
return league;
}
public void setLeague(String league) {
this.league = league;
}
public Integer getPoints() {
return points;
}
public void setPoints(Integer points) {
this.points = points;
}
}
#Controller
#RequestMapping(path="/init")
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#Autowired
private CharacterRepository characterRepository;
#GetMapping(path="/add") // Map ONLY GET Requests
public String addNewUser () {
User joueur = new User();
joueur.setUsername("testUser");
joueur.setPassword("password");
joueur.setLeague("Bronze");
joueur.setPoints(10000);
userRepository.save(joueur);
Character perso = new Character(joueur,"testPerso1",1000);
characterRepository.save(perso);
return "";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<User> getAllUsers() {
// This returns a JSON or XML with the users
return userRepository.findAll();
}
}
I have this error :
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'character add constraint Kdf2yvyvitaqt2u7de3ywfjcv foreign key (joueur_id) refe' at line 1
Ok I found the solution ... JPA annotation fordid the name of the table 'Character", just change the name of the table and it will work perfectly, stupid JPA ...

Get Column name along with JSON response

I have three entity classes, I have written the query which includes join of two tables.
Table: ExpensesCategories
#Entity
#Table(name = "ExpensesCategories")
public class ExpensesCategories {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id", unique = true)
private int categoryId;
#NotNull
private String categoryName;
#NotNull
private String categoryCodeInBankStats;
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryCodeInBankStats() {
return categoryCodeInBankStats;
}
public void setCategoryCodeInBankStats(String categoryCodeInBankStats) {
this.categoryCodeInBankStats = categoryCodeInBankStats;
}
}
Table: Transactions
#Entity
#Table(name = "TransactionHistory")
public class TransactionHistory {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Temporal(TemporalType.DATE)
private Date dateOfTransaction;
private String transactionType;
private String refNo;
private Date valueDate;
private double withdrawalAmount;
private double depositAmount;
private double closingBalance;
#ManyToOne
#JoinColumn(name="userDetailsId", referencedColumnName="user_id")
private UserDetails userDetails;
#ManyToOne
#JoinColumn(name="expenseCategoriesId", referencedColumnName="category_id")
private ExpensesCategories expenseCategories;
public TransactionHistory(int userId, Date dateOfTransaction, String transactionType, String refNo, Date valueDate,
double withdrawalAmount, double depositAmount, double closingBalance) {
this.dateOfTransaction = dateOfTransaction;
this.transactionType = transactionType;
this.refNo = refNo;
this.valueDate = valueDate;
this.withdrawalAmount = withdrawalAmount;
this.depositAmount = depositAmount;
this.closingBalance = closingBalance;
}
public TransactionHistory() {
}
public Date getDateOfTransaction() {
return dateOfTransaction;
}
public void setDateOfTransaction(Date date) {
this.dateOfTransaction = date;
}
public String getTransactionType() {
return transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public String getRefNo() {
return refNo;
}
public void setRefNo(String refNo) {
this.refNo = refNo;
}
public Date getValueDate() {
return valueDate;
}
public void setValueDate(Date valueDate) {
this.valueDate = valueDate;
}
public double getWithdrawalAmount() {
return withdrawalAmount;
}
public void setWithdrawalAmount(double withdrawalAmount) {
this.withdrawalAmount = withdrawalAmount;
}
public double getDepositAmount() {
return depositAmount;
}
public void setDepositAmount(double depositAmount) {
this.depositAmount = depositAmount;
}
public double getClosingBalance() {
return closingBalance;
}
public void setClosingBalance(double closingBalance) {
this.closingBalance = closingBalance;
}
public UserDetails getUserDetails() {
return userDetails;
}
public void setUserDetails(UserDetails userDetails) {
this.userDetails = userDetails;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public ExpensesCategories getExpenseCategories() {
return expenseCategories;
}
public void setExpenseCategories(ExpensesCategories expenseCategories) {
this.expenseCategories = expenseCategories;
}
}
Table: User Details
#Entity
#Table(name = "Employee")
public class UserDetails {
#Id
#Column(name = "user_id", unique = true)
private int id;
#NotNull
private String firstname;
#NotNull
private String lastname;
#Column(unique = true)
#NotNull
private String emailaddress;
#NotNull
private String role;
public UserDetails(String firstname, String lastname, String emailaddress, String role) {
this.firstname = firstname;
this.lastname = lastname;
this.emailaddress = emailaddress;
this.role = role;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public UserDetails() {
}
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 getEmailaddress() {
return emailaddress;
}
public void setEmailaddress(String emailaddress) {
this.emailaddress = emailaddress;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#Override
public String toString() {
return "Employee [id=" + id + ", firstname=" + firstname + ", lastname=" + lastname + ", emailaddress="
+ emailaddress + ", role=" + role + "]";
}
I have written query like this in transaction entity.
#Query( nativeQuery=true, value="SELECT a.expense_categories_id, a.Total_withdrawal_Amount, b.category_code_in_bank_stats, b.category_name FROM (SELECT expense_categories_id , SUM(withdrawal_amount) AS Total_withdrawal_Amount FROM transaction_history GROUP BY expense_categories_id) a join expenses_categories b on a.expense_categories_id = b.category_id
")
List<Object[]> getCategorizedExpenses();
My Json Response is like:
[
[
1,
21,
"UPI",
"UPI Payments"
],
[
2,
3733.59,
"POS",
"Shopping"
]
]
But i want json response with column names as well:
[
[
expense_categories_id: 1,
Total_withdrawal_Amount: 21,
category_code_in_bank_stats: "UPI",
category_name: "UPI Payments"
],
[
expense_categories_id: 2,
Total_withdrawal_Amount: 3733.59,
category_code_in_bank_stats: "POS",
category_name: "Shopping"
]
]
Please help me out..
You would need to map the results directly to a POJO class and ad some json config:
1) Define the pojo
public ResultClass implements Serializable{
#JsonProperty("expense_categories_id")
private Integer expenseCategoriesId;
...
public ResultClass(Integer expenseCategoriesId ... // rest params){
this.expenseCategoriesId = expenseCategoriesId;
...
}
}
2) Define the mapping:
#SqlResultSetMapping(
name="myMapping",
classes={
#ConstructorResult(
targetClass=ResultClass.class,
columns={
#ColumnResult(name="expenseCategoriesId"),
#ColumnResult(name="totalWithdrawalAmount")
// further mappings ...
}
)
}
)
3) Define a native query
#NamedNativeQuery(name="TransactionHistory.myQuery"
, query="SELECT new mypackage.ResultClass(a.expense_categories_id as expeneCategoriesId ... ) from ...")
4) Define this method in the CrudRepository without the #Query annotation:
public List<ResultClass> myQuery();
Teh #SqlResultSetMapping and #NamedNativeQuery would need to be defined on one of your mapped entities.
Your native query will give you an object[][] as an result. So, it actually a mxn rows.
So,
I think you should create a class names Response
public class Response{
private Long expense_categories_id;
private Double Total_withdrawal_Amount;
private String category_code_in_bank_stats;
private String category_name;
//getters and setters for all attributes
}
List<Response> fillCategorizedExpenses(){
List<Response> response_List = new ArrayList<>();
Response response = null;
Object[][] // fill each object with by accessing their index from
//this array.
for() //iterate the object array. {
response = new Response();
response.setExpense_categories_id(value); // set all attributes.
....
....
....
response_List.add(response);
}
return response_List; //this will print as you need in your project.
}
Thank You :) Hope this might help you out.

CassandraInvalidQueryException String didn't validate Composite Primary Query

I am trying to use Spring-Data-Cassandra with UserDefinedType and Compound Query Key. I am using 1.5.0.DATACASS-172-SNAPSHOT of the spring-cql and spring-data-cassandra. The code throws below exception.
Caused by: org.springframework.cassandra.support.exception.CassandraInvalidQueryException:
String didn't validate.; nested exception is com.datastax.driver.core.exceptions.InvalidQueryException:
String didn't validate.
Below is my code
#PrimaryKeyClass
public class EmployeeIdKey implements Serializable {
#PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED,name = "id")
#CassandraType(type = DataType.Name.UUID)
private UUID id;
#PrimaryKeyColumn(ordinal = 1,type = PrimaryKeyType.CLUSTERED, name = "user_id")
#CassandraType(type = DataType.Name.TEXT)
private String userId;
public EmployeeIdKey(){
id = null;
userId = null;
}
public UUID getUuId() {
return id;
}
public void setUuId(UUID uuId) {
this.id = uuId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
Employee.java
#Table("employee")
public class Employee {
#PrimaryKey
private EmployeeIdKey id;
private Person person;
#Column("employee_no")
private String employeeNo;
#Column("email_ids")
private List<String> emailId;
//Getters and setters
}
Person.java
#UserDefinedType
public class Person {
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Column("first_name")
private String firstName;
#Column("last_name")
private String lastName;
// Getters adn setters;
}
EmployeeRepository.java
public interface EmployeeRepository extends TypedIdCassandraRepository<Employee,EmployeeIdKey> {
}
App.java
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
#Bean
public CommandLineRunner demo( EmployeeRepository repository) {
Employee employee = new Employee();
EmployeeIdKey key = new EmployeeIdKey();
key.setUserId("55550");
key.setUuId(UUID.randomUUID());
employee.setId(key);
List<String> emailIds = Arrays.asList("myemail#domain.com","myemail2#domain2.com");
employee.setEmailId(emailIds);
Person person = new Person("John", "Mathew");
employee.setPerson(person);
repository.save(employee);
return null;
}
}
When I use simple primary key it works well.

How to populate foreign key in table Spring + Hibernate + Spring Security

I want make a case, when user is authenticated by Spring Security and then he fill adres form I would like to automatically updated a foreign key column "adres_id" in user table. Please give me a tip how implement this in the most popular way
I how somethig like this
Address Table:
User Table:
Adres
#Entity
#Table(name="adres")
public class Adres {
#Id
#GeneratedValue(strategy = GenerationType.AUTO )
int id;
#Column(name="country", nullable=false)
private String country;
private String street;
private String postcode;
private String telephone;
private String pesel;
#OneToOne(mappedBy ="adres")
private User user;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getPesel() {
return pesel;
}
public void setPesel(String pesel) {
this.pesel = pesel;
}
public String getStreet() {
return postcode;
}
public void setStreet(String street) {
this.street = street;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
User
#Entity
#Table(name="users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO )
int id;
#Column(name="username", nullable=false)
private String username;
private String password;
private String email;
private Boolean enabled;
#OneToOne(cascade = CascadeType.ALL)
private Adres adres;
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
AdresDAO
#Repository
#Transactional
public class AdresDAOImpl implements AdresDAO{
#Autowired
SessionFactory sessionFactory;
public void addAdres(Adres adres) {
sessionFactory.getCurrentSession().save(adres);
}
public List<Adres> listAdres() {
return sessionFactory.getCurrentSession().createQuery("from Adres order by id").list();
}
public void removeAdres(int id) {
Adres adres = (Adres) sessionFactory.getCurrentSession().load(
Adres.class, id);
if (null != adres) {
sessionFactory.getCurrentSession().delete(adres);
}
}
public Adres getAdres(int id) {
return (Adres)sessionFactory.getCurrentSession().get(Adres.class, id);
}
public void editAdres(Adres adres) {
sessionFactory.getCurrentSession().update(adres);
}
}
AdresService
#Service
public class AdresServiceImpl implements AdresService{
#Autowired
AdresDAO adresDAO;
#Transactional
public void addAdres(Adres adres) {
adresDAO.addAdres(adres);
}
#Transactional
public void editAdres(Adres adres) {
adresDAO.editAdres(adres);
}
#Transactional
public List<Adres> listAdres() {
return adresDAO.listAdres();
}
#Transactional
public void removeAdres(int id) {
adresDAO.removeAdres(id);
}
#Transactional
public Adres getAdres(int id) {
return adresDAO.getAdres(id);
}
}
User unidirectional relation between User and Address if Address object does not supposed to know about its owner (generally it does not). I would prefer user id in Address table if a User have more than one Address (one-to-many relation).
But for your question you may design like that,
public class User{
...
#OneToOne(CascadeType.REMOVE)//this is for to remove address when user is removed
#JoinColumn(name="HOME_ADDRESS_ID")
private Address address;
...
}
and
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO )
int id;
#Column(name="country", nullable=false)
private String country;
private String street;
private String postcode;
private String telephone;
private String pesel;
//no user object here
public int getId() {
return id;
}
...
}

Categories

Resources