I have a problem. After clicking on the "create order" button, the user is redirected to the URL: "localhost:8080/currentorder/{id}" After visiting this URL, the user should see order.text.
Attempts to solve: In the DAO, I create a method that, by the ID passed from the controller, looks for an order in HQL:
public List show(Long id) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
Query query = session.createQuery("from Order where id = :id");
query.setParameter("id", id);
List result = query.getResultList();
session.getTransaction().commit();
return result;
}
}
But as you understand, after that, the timelif could not display anything (I mean order.getStatus()) Now I still think that I need to search the database and return an object, but how? help me please
My code:
Controller
#PostMapping("/")
public String createOrder (#ModelAttribute("order") Orderdao orderdao, String text, Model model, RedirectAttributes redirectAttributes){
orderdao.createOrder(text);
redirectAttributes.addAttribute("id", orderdao.checkLastOrder());
return "redirect:/currentorders/{id}";
}
#GetMapping("/currentorders/{id}")
public String showOrder (#PathVariable("id") Long id, Orderdao orderdao, Model model, Order order){
model.addAttribute("currentOrder", orderdao.show(id));
return "order";
}
Entity
#Entity
#Table(name = "orders")
public class Order implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String text;
private String customer;
private int status;
public Order(String text, String customer, int status) {
this.text = text;
this.customer = customer;
this.status = status;
}
public Order(String customer) {
this.customer = customer;
}
public Order(){
}
//Getters and setters
Method:
public Order show(Long id) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
Query query = session.createQuery("from Order where id = :id");
query.setParameter("id", id);
List result = (List) query.getSingleResult();
session.getTransaction().commit();
return (Order) session.save(result);
}
}
I am missing your code for orderDao.create, but usually you would have a service class (annotated with Springs #Service annotation), which is injected to the controller and which is called to create the entity. You can make this service method return the ID of the just created entity. It could hence be something like public Long createOrder(OrderDao orderDao). Inside there, after calling repository.save(entity), the entity will already have the ID set (try to verify yourself with debugger: Set a breakpoint to the line before you save the entity and check the ID is null, then go one step forward and see that after save, the ID is set).
My answer:
public Order show(Long id) {
Transaction tx = null;
try (Session session = BogPomogi.getSessionFactory().openSession()) {
session.beginTransaction();
Query query = session.createQuery("select text from Order where id = :id");
query.setParameter("id", id);
String result = (String) query.getSingleResult();
session.getTransaction().commit();
session.close();
return new Order(result, "adsfreger", 1);
}
}
Related
Repository Class:
#Repository // This my architecture repository class.
public class UserRepositoryImp implements UserRepository {
private EntityManager entityManager;
#Autowired
public UserRepositoryImp(EntityManager entityManager) {
this.entityManager = entityManager;
}
private static final String MY_SQL_COUNT_EMAIL =
"SELECT count(e) FROM User e WHERE e.email=:email "; // This is hibernate query.
#Override
public Integer getCountByEmail(String email) {
Session session = entityManager.unwrap(Session.class);
TypedQuery<Integer> query = session.createQuery(MY_SQL_COUNT_EMAIL, null);
query.setParameter("email", email); // This is return count in database check database
// .. if you email this database passing already exist this email but your count zero created new email.
return query.executeUpdate();
}
}
Service Class:
#Service
#Transactional
public class UserServiceImp implements UserService {
#Autowired
UserRepository userRepository;
#Override
public User validateUser(String email, String password) throws EtAuthException {
return null;
}
#Override
public User registerUser(User user) throws EtAuthException {
Pattern pattern = Pattern.compile("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2, 6} $ "); // This regex.
if (pattern.matcher(user.getEmail()).matches()) {
throw new EtAuthException("Invalid email format"); // This is check email regex.
}
Integer count = userRepository.getCountByEmail(user.getEmail()); // This is my method
// .. count email in database and repository methods
if (count > 0) {
throw new EtAuthException("Email already in use");
}
Integer userId = userRepository.create(user);
return userRepository.findById(userId);
}
}
Postman Error:
Cannot invoke "java.lang.Class.isAssignableFrom(java.lang.Class)"
because "resultClass" is null"
Problem:
My problem is actually. I want to write a query to hibernated but for some reason it doesn't work. For such operations in spring boot, ie typing a query, for example polling email, put delete add and updated, how do I do it? I need to query me. I can't solve this problem.
You are calling executeUpdate() for a select query. Try using getSingleResult() instead.
#Override
public long getCountByEmail(String email) {
Session session = entityManager.unwrap(Session.class);
String query = "SELECT count(e) FROM User e WHERE e.email = :email";
TypedQuery<Long> typedQuery = session.createQuery(query, Long.class);
typedQuery.setParameter("email", email);
return typedQuery.getSingleResult();
}
OR
#Override
public long getCountByEmail(String email) {
String query = "SELECT count(e) FROM User e WHERE e.email = :email";
TypedQuery<Long> typedQuery = entityManager.createQuery(query, Long.class);
typedQuery.setParameter("email", email);
return typedQuery.getSingleResult();
}
I am trying to update some user information by passing List of User-Ids as parameter
i want to update isActive field of User fo which i am passing the user ids.
Below is my controller
#PutMapping
#ResponseStatus(HttpStatus.OK)
#RequestMapping("/UserUpdate")
public ResponseEntity<?> updateUsers(List<Long> userIds) {
**userService.updateUsers(userIds);**
return ResponseEntity.ok(200);
}
updateUsers() is a method in my Service where i have to write the logic
I tried something like below but it's not working
public void updateUsers(List<Long> userIds) {
List<Users> userList= userRepository.findAll();
for (Long i : userIds) {
for ( Users user : userList)
{
if(userRepository.findById(i) != null)
{
user.setIsActive(9L);
user.setUserName("Update Test");
}
my dto
public class UserDto {
private List<Users> userList;
private String appName="Users Project";
// getters and setters removed for brevity
And my Users entity class
#Entity
#Table(name="USERS")
public class Users {
#Id
#Column(name="USER_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
#Column(name="NAME")
private String userName;
#Column(name="ACTIVE")
private Long isActive;
// getters and setters removed for brevity
Alternatively you can use the following code
#Modifying
#Query("update Users u set u.isActive = ?1, u.userName = ?2 where u.userId in ?3")
void updateUsers(Long isActive, String userName, List<Long> userId);
Add this code in your userRepository and use the method.
public void updateUsers(List<Long> userIds) {
for (Long i : userIds) {
User user = userRepository.findById(i);
if(user != null){
user.setIsActive(9L);
user.setUserName("Update Test");
// call your update method here (this is not stated in your code)
}
}
}
I've read a lot of topics dedicated to working with PostgreSQL arrays in Hibernate.
I implemented UserType interface and my queries are working perfectly fine with native sql.
private void addCountry(String country, String[] cities) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Query insert = session.createNativeQuery("INSERT INTO public.\"countries\"(\n" +
"\t\"country\", \"cities\")\n" +
"\tVALUES (:Country, :Cities);");
Type arrayType = new CustomType(new StringUserType());
insert.setParameter("Country", country);
insert.setParameter("Cities", cities, arrayType);
insert.executeUpdate();
/**
CountriesEntity countriesEntity = new CountriesEntity();
countriesEntity.setCountry(country);
countriesEntity.setCities(cities);
session.save(countriesEntity);
*/
session.getTransaction().commit();
}
private List<String[]> listCities() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Query getCities = session.createNativeQuery("SELECT \"cities\"\n" +
"\tFROM public.\"countries\";")
.addScalar("cities", new CustomType(new StringUserType()));
List<String[]> cities = getCities.list();
session.getTransaction().commit();
return cities;
}
Entity class:
#Entity
#Table(name = "countries", schema = "public", catalog = "Travel_Agency")
public class CountriesEntity {
private String country;
private String[] cities;
#Id
#Column(name = "country")
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Column(name = "cities")
#Type(type = "com.testHibernate.core.StringUserType")
public String[] getCities() {
return cities;
}
public void setCity(String[] cities) {
this.cities = cities;
}
}
So, is it possible to do that using only HQL?
You are using createSQLQuery(String queryString) which creates a SQLQuery instance for the given SQL query string.
It is possible by using createQuery(String query) method, that will create a Query instance for the given HQL query string. For example retrieving a cities where city name is cityName:
Query getCities = session.createQuery("FROM countries WHERE cityName = :city ");
getCities.setParameter("city", "cityName");
return query.list();
Here is the documentation of The Hibernate Query Language.
I'm trying to remove an entity from memory (at the moment I don't use DB) with JPA, when I use remove and then try to find the deleted entity it shows null, but when I use findAll method it retrieve all data (with removed entity)...
Profile.java
#Entity
#Table(name = "profile")
public class Profile {
#Id
#GeneratedValue
private Long id;
private String nombre;
private Boolean restrictedAccess;
private Boolean canValidate;
// private Set<AccessField> accessFields = new HashSet<AccessField>();
// private Set<AccessEntity> accessEntities = new HashSet<AccessEntity>();
#OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
private Set<AccessMenu> menuSections = new HashSet<AccessMenu>();
#OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
private Set<User> users = new HashSet<User>();
[getters and setters]
ProfileRepository
#Repository
#Transactional
public class ProfileRepository {
#PersistenceContext
private EntityManager entityManager;
public Profile save(Profile p) {
p = this.entityManager.merge(p);
this.entityManager.flush();
return p;
}
public void delete(Long id){
Profile profile = this.entityManager.find(Profile.class, id);
this.entityManager.remove(profile);
}
public List<Profile> findAll() {
CriteriaQuery cq = this.entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(Profile.class));
return (List<Profile>) this.entityManager.createQuery(cq).getResultList();
}
public Profile findById(Long id){
return this.entityManager.find(Profile.class, id);
}
}
Controller method
#RequestMapping(value="profile/delete/{idProfile}", method = RequestMethod.GET)
public String delete(#PathVariable String idProfile,RedirectAttributes ra, Model model){
profileRepo.delete(Long.valueOf(idProfile));
model.addAttribute("profiles", profileRepo.findAll());
return "profile/list";
}
if you are are trying to delete an entity by using Id in the controller, do it like profileRepo.deleteById(Long.valueOf(idProfile));
this, not like this profileRepo.delete(profileRepo.findById(Long.valueOf(idProfile)));
Also use your repository functions like these,
public void deleteArtistById(Long artistId) {
Artist artist = manager.find(Artist.class, artistId);
if (artist != null) {
manager.getTransaction().begin();
manager.remove(artist);
manager.getTransaction().commit();
}
}
public void deleteArtist(Artist artist) {
manager.getTransaction().begin();
manager.remove(artist);
manager.getTransaction().commit();
}
You can take a look at this link for more detail:
http://kodejava.org/how-do-i-delete-entity-object-in-jpa/
At last I found a solution, the problem was when I tried to remove Profile, users and menuSections have related data, so finally I put in menuSections a cascade = CascadeType.REMOVE and in users set profile property to null
So I keep coming up short on this, and just can't seem to get it to work right.
Things seem to work fine when I use my HibernateUtil.get(clazz, pkId) method, but when I try using the HibernateUtil.pagedQuery(clazz, criterion, start, stop) I get multiple identical objects returned.
For example if there were 3 employees assigned to Role 1, then running...
Role role = HibernateUtil.get(Role.class, new Integer(1));
... works as expected. However, if I run...
List<Criterion> c = new ArrayList();
c.add(Restrictions.eq("roleTypeSeqNo", new Integer(1)));
List<Role> roles = (List<Role>) phi.util.hibernate.HibernateUtil.pagedQuery(Role.class, c, 0, 50);
... returns a List of 3 identical roles. All of which represent Role 1.
If someone could guide me down the right path, I would really appreciate it.
Thanks in advance!
Here's an abbreviated version of my classes
#Entity
#Table(name="ASSIGNMENTS")
public class Assignment implements Serializable {
#EmbeddedId
private AssignmentPK pk;
// After coming across many errors I finally caved and reverted roleTypeSeqNo back to just an Integer.
private Integer roleTypeSeqNo;
private String status;
private String location;
}
#Embeddable
public class AssignmentPK implements Serializable {
#ManyToOne
#JoinColumn(name="EMPLID")
private Employee employee;
#Column(name="PRIORITY_NO")
private String priorityNo;
}
#Entity
public class Employee implements Serializable {
#Id
private Integer emplId;
private String name;
}
#Entity
public class Role implements Serializable {
#Id
private Integer roleTypeSeqNo;
private Integer reportsToRole;
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="roleTypeSeqNo")
#JoinTable(
name="ASSIGNMENTS"
, joinColumns={#JoinColumn(name="ROLE_TYPE_SEQ_NO")}
, inverseJoinColumns={
#JoinColumn(name="EMPLID"),
#JoinColumn(name="PRIORITY_NO")
}
)
private List<Assignment> assignments;
}
public class HibernateUtil {
public static Object get(Class clazz, Serializable pkId) {
Session session = getSession();
Transaction transaction = session.beginTransaction();
Object obj = session.get(clazz, pkId);
transaction.commit();
session.close();
return obj;
}
public static List pagedQuery(Class clazz, List<Criterion> criterion, Integer start, Integer size){
Session session = getSession();
try {
Transaction transaction = session.beginTransaction();
DetachedCriteria dCriteria = DetachedCriteria.forClass(clazz);
for(Criterion c : criterion){
dCriteria.add(c);
}
dCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
dCriteria.setProjection(Projections.id());
Criteria criteria=session.createCriteria(clazz);
criteria.add(Subqueries.propertyIn("id", dCriteria));
criteria.setFirstResult(start);
criteria.setMaxResults(size);
List records = criteria.list();
transaction.commit();
return records;
} catch (Exception e) {
Logger.getLogger("HibernateUtil").log(Level.SEVERE, "There was an EXCEPTION THROWN!!!", e);
return null;
} finally {
session.close();
}
}
}
dCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
should be on the main criteria
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
Also there is no need for the subquery there. The following is enough
Criteria criteria = session.createCriteria(clazz);
for(Criterion c : criterions){
criteria.add(c);
}
criteria.setFirstResult(start);
criteria.setMaxResults(size);
List records = criteria.list();