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
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.");
}
}
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 ...
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.
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.
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;
}
...
}