Spring Hibernate: Values not inserting into database - java

I can't seem to add values to my table. There is no error but the values aren't inserting in my database. After submitting the form, no errors would show up.
Upon looking at the console, this shows:
Hibernate:
insert
into
referral
(address, doctor_contact_no, doctor_name, facility_contact_no, facility_type, referral_no, referring_from, referring_to)
values
(?, ?, ?, ?, ?, ?, ?, ?)
I already tried logging, just in case my controller can't read the form i'm submitting.
Code Snippet of the Entity/Model i am saving
#Entity
#Table(name="referral")
public class Referrals {
#Id
#Column
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#Column
private String referral_no;
#Column
private String facility_contact_no;
#Column
private String referring_from;
#Column
private String referring_to;
#Column
private String facility_type;
#Column
private String address;
#Column
private String doctor_name;
#Column
private String doctor_contact_no;'
Code Snippet of my Services Class
#Service
#Transactional
public class ReferralServicesImpl implements ReferralServices{
#Autowired
private ReferralDao referralDao;
public List<Referrals> list(){
return referralDao.list();
}
public boolean saveReferral(Referrals referral){
if(referralDao.saveReferral(referral))
return true;
else
return false;
}
}
Code Snippet of the Controller Methods
#RequestMapping(value = "/teleaudiology/referral", method = RequestMethod.GET)
public ModelAndView showForm() {
return new ModelAndView("referrals", "referrals", new Referrals());
}
#RequestMapping(value = "/teleaudiology/referrals", method = RequestMethod.POST)
public String submit(#Valid #ModelAttribute("referrals")Referrals referral,
BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "error";
}
System.out.println("referral: "+referral.getDoctor_name());
if(referralServices.saveReferral(referral))
return "redirect:../teleaudiology";
else
return "redirect:../teleaudiology";
}
Here is the ReferralDao Class
public interface ReferralDao {
public boolean saveReferral(Referrals referral);
public List<Referrals> list();
}
ReferralDao impl
#Repository
#Transactional
public class ReferralDaoImpl implements ReferralDao {
#Autowired
SessionFactory session;
Transaction trans;
public boolean saveReferral(Referrals referral) {
// TODO Auto-generated method stub
//System.out.println("Saving..."+referral.getReferring_to_address());
trans=session.getCurrentSession().beginTransaction();
session.getCurrentSession().saveOrUpdate(referral);
return true;
}
public List<Referrals> list() {
// TODO Auto-generated method stub
return session.getCurrentSession().createQuery("from Referrals").list();
}
}
i tried using
trans=session.getCurrentSession().getTransaction();
but resulted to this error
`saveOrUpdate is not valid without active transaction`
Snippet from servlet-context.xml
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>

try using below code
Session s = sessionFactory.getCurrentSession();
s.save(object);

Related

How to fix unsatisfied dependencies for injecting Models (javax.mvc.Models)?

I get this error while following this tutorial for mvc 1.0.
[ERROR] Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Models with qualifiers #Default at injection point [BackedAnnotatedField] #Inject ch.xxx.controller.UserController.models at ch.xxx.controller.UserController.models(UserController.java:0)
I tried...
putting my beans.xml into multiple places (resources/META-INF/beans.xml | webapp/WEB-INF/beans.xml)
changing the bean-discovery-mode to "all"
annotated my User.class with #Named and/or #SessionScoped (not in tutorial)
This is my User.class
#Entity
#Table(name = "users")
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String email;
private String password;
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;
}
}
Here my UserForm.class
import javax.ws.rs.FormParam;
public class UserForm {
#FormParam("id")
private String id;
#FormParam("email")
private String email;
#FormParam("password")
private String password;
public String getId() {
return id;
}
public void setId(String 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;
}
}
and at last my UserController.class, where the error actually happens:
#Controller
#Stateless
#Path("/user")
public class UserController {
#PersistenceContext
EntityManager entityManager;
#Inject
Models models;
#GET
#View("user/all-users.html")
public void getAllREST(){
List<User> allUsers = entityManager.createNamedQuery("User.findAll", User.class).getResultList();
models.put("users", allUsers);
}
#GET
#Path("/create")
public String getCreateRESTForm(){
return "user/create-user.html";
}
#POST
#Path("/create")
public String create(#BeanParam UserForm userForm){
User user = new User();
user.setEmail(userForm.getEmail());
user.setPassword(user.getPassword());
entityManager.persist(user);
return "redirect:/user";
}
}
I'm really lost here, since I have no idea what more to change and what the actual problem is for such a simple form. And don't mind the plain text password, it's just for testing.
I have not worked with JEE MVC yet but this seems to be CDI related issue and should not be located in the MVC framework, because it should only make use of CDI.
The reason for this exception, as already answered, is because the CDI Container does not find any injectible implementations of this interface, and therefore cannot inject it.
Take a look at the javadoc which says, that any implementation of this interface needs to be injectible and request scoped. Are you sure that the implementing bean you expect fulfills these requirements?
https://github.com/javaee/mvc-spec/blob/master/api/src/main/java/javax/mvc/Models.java
Is there a beans.xml present in the artifact the bean resides?
src/main/reosurces/META-INF/beans.xml (for JAR)
src/main/webapp/WEB-INF/beans.xml (for WAR)
Is the implementing bean annotated with #RequestScoped?
If referenced via EL, is the bean annotated with #Named?
Another thing is, do not make JPA entities CDI-Beans and make them injectible, this is a bad approach and the Models interfaces and its implementations should not require it.

Clarify the sequence of events in a Spring MVC ORM web app project

My professor gave a sample Spring MVC ORM project with Hibernate but I can not figure out the sequence of events involved, in particular about the usage of service business object.
This is just a little part of the project, just to make my ideas clearer.
domain:
#Entity
#Table(name = "department")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long uid;
private String name;
#OneToMany(mappedBy="department",cascade=CascadeType.PERSIST)
private List<Employee> employees = new ArrayList<Employee>();
public Department() {
}
public Department(String name) {
this.name = name;
}
// getters, setters, hashcode() and equals(), toString()...
controller:
#Controller
#RequestMapping("/department")
public class DepartmentController {
#Autowired
#Qualifier("departmentBO")
private DepartmentBO departmentBO;
static final Logger logger = Logger.getLogger(DepartmentController.class);
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String departmentHome(Model model) {
logger.debug("department home() invoked");
List<Department> list = departmentBO.findAllDepartments();
model.addAttribute("list", list);
return "departments";
}
// i'll paste just the first controller ;)
business:
public interface DepartmentBO {
public void delete(long uid);
public List<Department> findAllDepartments();
public Department findByUid(Long uid);
public void save(Department department);
public void update(Department department);
}
business/impl:
#Service
#Transactional
public class DepartmentBoImpl implements DepartmentBO {
#Autowired
private DepartmentDAO departmentDao;
static final Logger logger = Logger.getLogger(DepartmentBoImpl.class);
#Override
public void save(Department department) {
departmentDao.save(department);
}
#Override
public void update(Department department) {
departmentDao.update(department);
}
#Override
public void delete(long uid) {
departmentDao.delete(uid);
}
#Override
public List<Department> findAllDepartments() {
return departmentDao.findAllDepartments();
}
#Override
public Department findByUid(Long uid) throws DataAccessException {
return departmentDao.findByUid(uid);
}
}
dao:
public interface DepartmentDAO {
public void delete(long uid);
public List<Department> findAllDepartments();
public Department findByUid(Long uid);
public void save(Department user);
public void update(Department user);
}
dao/impl:
#Repository
public class DepartmentDAOImplSf implements DepartmentDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
public void delete(long uid) {
Department department = (Department) sessionFactory.getCurrentSession()
.get(Department.class, uid);
sessionFactory.getCurrentSession().delete(department);
}
#Override
public void save(Department department) {
sessionFactory.getCurrentSession().save(department);
}
#Override
public void update(Department department) {
sessionFactory.getCurrentSession().saveOrUpdate(department);
}
#Override
public List<Department> findAllDepartments() {
List<Department> list = (List<Department>) sessionFactory
.getCurrentSession()
.createQuery("FROM Department").list();
return list;
}
#Override
public Department findByUid(Long uid) {
Department department = (Department) sessionFactory
.getCurrentSession().get(Department.class, uid);
return department;
}
}
I know that the order is: domain model -> controller-> service -> dao ->db, but why use a DepartmentBO? and why DepartmentBoImpl autowired DepartmentDao? Who of them act first? Something that i'm not understanding is messing up my conception of how it works and the sequence of the process..
Thanks for your help ;)
EDIT: "
In few words my question is, what is the sequence of this code? user goes on the /home page that redirect on "departments" page. But what happen before this --> "List list = departmentBO.findAllDepartments();" ?;)
When the departmentBO.findAllDepartments() method is called if you look at the code it invokes the sessionFactory. That is an internal factory class in Hibernate that basically builds a transactional connection to the DB in order to run a query. You are defining the query in the createQuery method and then ultimately executing it with the list() method. These two methods are part of the database session that Hibernate has instantiated.
Departments Page -> departmentBO.findAllDepartments() -> sessionFactory -> createQuery -> list()
Or in pseudo code-ish
Departments Page -> execute findAllDepartments method -> fetch / build a database connection -> define the query -> execute the query -> Return the list!

Spring: detached entity passed to persist

It is a short time that I'm studying Spring,I'm a student
I have problems with dependency injection. In this project I have this error code in the method acquista.Why? Acquista in english is translated in "buy".If my Carrello (cart) is composed by more than one Articolo(Article) , in ArticoliOrdine(ArticlesOrder) I have only the first of them.Why?How can I solve it?
Error code:
Grave: Servlet.service() for servlet [applicationContext] in context with path [/SpringStore] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: bean.Ordine] with root cause
org.hibernate.PersistentObjectException: detached entity passed to persist: bean.Ordine
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
at com.sun.proxy.$Proxy37.persist(Unknown Source)
at daoJPA.CarrelloDAOImpl.acquista(CarrelloDAOImpl.java:130)
CarrelloDAOImpl.java
#Transactional
public class CarrelloDAOImpl implements CarrelloDAO {
#PersistenceContext
private EntityManager em;
#Autowired
Carrello carrello;
#Autowired
private ArticoliOrdine articoliOrdine;
#Autowired
private Ordine ordine;
public void acquista(Cliente c){
ordine.setIdCliente(c);
ordine.setData(new Date(System.currentTimeMillis()));
ordine.setStato("In lavorazione");
em.persist(ordine);
Set<String> lista_articoli=carrello.getMappa_Articoli().keySet();
synchronized(lista_articoli){
Iterator<String> it=lista_articoli.iterator();
while(it.hasNext()){
String codice=it.next();
System.out.println("codice: "+codice);
Query q=em.createQuery("SELECT a FROM Articolo a WHERE a.codice =:codice");
q.setParameter("codice", codice);
Articolo a =(Articolo)q.getSingleResult();
ArticoliOrdinePK pk=articoliOrdine.getArticoliordinePK();
pk.setIdArticolo(a.getId());
pk.setIdOrdine(ordine.getId());
articoliOrdine.setArticolo(a);
articoliOrdine.setQuantita(carrello.getMappa_Articoli().get(codice));
em.persist(articoliOrdine);
//aggiorno la quantita' dell'articolo
Articolo articolo_update=em.find(Articolo.class,a.getId());
articolo_update.setQuantita(articolo_update.getQuantita()- articoliOrdine.getQuantita());
}//while
}//syncronized
}//acquista
}//CarrelloDAOImpl
Ordine.java
#Table(name="ordine")
#Entity
public class Ordine implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="data")
private Date data;
#Column(name="stato")
private String stato;
#ManyToOne(optional=false)
#JoinColumn(name="idCliente",referencedColumnName="id")
private Cliente idCliente;
#OneToMany(mappedBy="ordine",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
Collection<ArticoliOrdine> articoliordineCollection;
public Ordine() {
}
public Ordine(Integer id) {
this.id = id;
}
public Ordine(Integer id, Date data, String stato) {
this.id = id;
this.data = data;
this.stato = stato;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getData() {
return data;
}
public void setData(Date data) {
this.data = data;
}
public String getStato() {
return stato;
}
public void setStato(String stato) {
this.stato = stato;
}
public Cliente getIdCliente() {
return idCliente;
}
public void setIdCliente(Cliente idCliente) {
this.idCliente = idCliente;
}
public Collection<ArticoliOrdine> getArticoliordineCollection() {
return articoliordineCollection;
}
public void setArticoliordineCollection(
Collection<ArticoliOrdine> articoliordineCollection) {
this.articoliordineCollection = articoliordineCollection;
}
#Override
public boolean equals(Object o){
if(! (o instanceof Ordine) )
return false;
Ordine ordine=(Ordine)o;
return ordine.id==this.id;
}//equals
public String toString(){
return id+" cliente:"+idCliente.getId();
}//toString
}//Ordine
CarrelloController.java
#Controller
public class CarrelloController {
#Autowired
CarrelloDAO carrelloDAO;
#Autowired
Carrello carrello;
...
#RequestMapping(value="/acquista",method=RequestMethod.POST)
public String acquista(HttpServletRequest request,ModelMap model){
HttpSession session=request.getSession();
Cliente cliente=(Cliente)session.getAttribute("cliente");
carrelloDAO.acquista(cliente);
carrello.svuotaCarrello();
model.addAttribute("num_articoli",carrello.contaArticoliCarrello());
model.addAttribute("totale_carrello",carrello.getTotale());
return "redirect:/";
}//checkOut
}//CarrelloController
ApplicationContext.xml
<bean class="daoJPA.ClienteDAOImpl" id="clienteDAO"/>
<bean class="daoJPA.ArticoloDAOImpl" id="articoloDAO"/>
<bean class="bean.Carrello" id="carrello" scope="session">
<aop:scoped-proxy/>
</bean>
<bean class="daoJPA.CarrelloDAOImpl" id="carrelloDAO"/>
<bean class="bean.ArticoliOrdine" id="articoliOrdine" scope="prototype">
<property name="articoliordinePK">
<bean class="bean.ArticoliOrdinePK" id="articoliOrdinePK" scope="prototype"/>
</property>
</bean>
<bean class="bean.Ordine" id="ordine" scope="prototype"/>
You are not approaching this the right way. Your entities shouldn't be treated as Spring Beans.
#Autowired
private ArticoliOrdine articoliOrdine;
...
em.persist(articoliOrdine);
For long conversations you should either use:
Extended persistence context
detached objects saved in your Http Session
And detached entities shouldn't be passed to persist. You should merge them instead.
Persist is only meant for moving an entity state from TRANSIENT to PERSISTED. For DETACHED -> PERSISTED transitions you should always use EntityManager#merge() or Hibernate specific saveOrUpdate.

Is it possible to use raw SQL within a Spring Repository

I need to use raw SQL within a Spring Data Repository, is this possible? Everything I see around #Query is always entity based.
The #Query annotation allows to execute native queries by setting the nativeQuery flag to true.
Quote from Spring Data JPA reference docs.
Also, see this section on how to do it with a named native query.
YES, You can do this in bellow ways:
1. By CrudRepository (Projection)
Spring Data Repositories usually return the domain model when using query methods. However, sometimes, you may need to alter the view of that model for various reasons.
Suppose your entity is like this :
import javax.persistence.*;
import java.math.BigDecimal;
#Entity
#Table(name = "USER_INFO_TEST")
public class UserInfoTest {
private int id;
private String name;
private String rollNo;
public UserInfoTest() {
}
public UserInfoTest(int id, String name) {
this.id = id;
this.name = name;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", nullable = false, precision = 0)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "name", nullable = true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "roll_no", nullable = true)
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
}
Now your Projection class is like below. It can those fields that you needed.
public interface IUserProjection {
int getId();
String getName();
String getRollNo();
}
And Your Data Access Object(Dao) is like bellow :
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.ArrayList;
public interface UserInfoTestDao extends CrudRepository<UserInfoTest,Integer> {
#Query(value = "select id,name,roll_no from USER_INFO_TEST where rollNo = ?1", nativeQuery = true)
ArrayList<IUserProjection> findUserUsingRollNo(String rollNo);
}
Now ArrayList<IUserProjection> findUserUsingRollNo(String rollNo) will give you the list of user.
2. Using EntityManager
Suppose your query is "select id,name from users where roll_no = 1001".
Here query will return an object with id and name column. Your Response class is like bellow:
Your Response class is like this:
public class UserObject{
int id;
String name;
String rollNo;
public UserObject(Object[] columns) {
this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
this.name = (String) columns[1];
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
}
here UserObject constructor will get an Object Array and set data with the object.
public UserObject(Object[] columns) {
this.id = (columns[0] != null)?((BigDecimal)columns[0]).intValue():0;
this.name = (String) columns[1];
}
Your query executing function is like bellow :
public UserObject getUserByRoll(EntityManager entityManager,String rollNo) {
String queryStr = "select id,name from users where roll_no = ?1";
try {
Query query = entityManager.createNativeQuery(queryStr);
query.setParameter(1, rollNo);
return new UserObject((Object[]) query.getSingleResult());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
Here you have to import bellow packages:
import javax.persistence.Query;
import javax.persistence.EntityManager;
Now your main class, you have to call this function. First get EntityManager and call this getUserByRoll(EntityManager entityManager,String rollNo) function. The calling procedure is given below:
Here is the Imports
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
get EntityManager from this way:
#PersistenceContext
private EntityManager entityManager;
UserObject userObject = getUserByRoll(entityManager,"1001");
Now you have data in this userObject.
Note:
query.getSingleResult() return a object array. You have to maintain the column position and data type with the query column position.
select id,name from users where roll_no = 1001
query return a array and it's [0] --> id and [1] -> name.
More info visit this thread and this Thread
Thanks :)
It is possible to use raw query within a Spring Repository.
#Query(value = "SELECT A.IS_MUTUAL_AID FROM planex AS A
INNER JOIN planex_rel AS B ON A.PLANEX_ID=B.PLANEX_ID
WHERE B.GOOD_ID = :goodId",nativeQuery = true)
Boolean mutualAidFlag(#Param("goodId")Integer goodId);
we can use createNativeQuery("Here Native SQL Query ");
for Example :
Query q = em.createNativeQuery("SELECT a.firstname, a.lastname FROM Author a");
List<Object[]> authors = q.getResultList();
This is how you can use in simple form
#RestController
public class PlaceAPIController {
#Autowired
private EntityManager entityManager;
#RequestMapping(value = "/api/places", method = RequestMethod.GET)
public List<Place> getPlaces() {
List<Place> results = entityManager.createNativeQuery("SELECT * FROM places p limit 10").getResultList();
return results;
}
}
It is also possible to use Spring Data JDBC, which is a fully supported Spring project built on top of Spring Data Commons to access to databases with raw SQL, without using JPA.
It is less powerful than Spring Data JPA, but if you want lightweight solution for simple projects without using a an ORM like Hibernate, that a solution worth to try.

Spring mvc: Transactional annotation

I have two tables Employee and Address as shown:
public class Employee {
private Integer id;
private String firstName;
private String lastName;
private boolean employeeStatus;
private Address address;
//getters setters
}
public class Address {
private Integer id;
private String country;
private String city;
private String street;
private Integer emp_id;
//getters setters
}
#Repository("employeeDao")
public class EmployeeDaoImpl implements EmployeeDao {
private JdbcTemplate jdbcTemplate;
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
public void insertEmployee(Employee e)
{
String sql = "INSERT INTO tbl_employee (dept_id,firstName,lastName,employeeStatus) values(?,?,?,?,?)";
this.jdbcTemplate.update(sql,new
Object[]{e.getDept_id(),e.getFirstName(),e.getLastName(),e.isEmployeeStatus()});
// INSERT ADDRESS????
}
// Other Methods
}
Now i want to implement Transactional while inserting the employee and address table attributes. I am abit confused here. Does #transactional annotation over the method does the required job? So far i understood that. Also, is it best practice to insert address from where i am inserting employee attributes? I also read somewhere that the transactional should be implemented from service layer than Dao. How would transactional can be implemented in this case?
EDIT
Since it is recommended to use #transactional in service layer, service layer became like:
#Service("employeeService")
#Transactional
public class EmployeeServiceImpl implements EmployeeService{
#Autowired
EmployeeDao employeeDao;
#Autowired
AddressDao addressDao;
#Override
public void insertEmployee(Employee e) {
employeeDao.insertEmployee(e);
addressDao.insertAddress(e.address);
}
}
is it the right way to perform transactional? Also can anyone explain #Transactional(propagation = Propagation.SUPPORTS, readOnly = true) instead of plain #Transactional ?
Alltough the #Transactional annotation would do the job, transactions are usually defined on service level. This way one business call is in one transaction, making sure everything succeeds or fails together.
you can read about #transactional in combination with jdbctemplate here

Categories

Resources