I am new in hibernate and I am struggling with a problem. I want to display a list of objects to a .XHTML page using JSF. But I don't know why, I lose the data on the way. Even though the method from DAO returns a list of objects from database (I saw it by doing debug) when I try to assign that list to a list of users from another class I loose that data and the list from DAO becomes null. So there are no results in GUI from my datatable.
public class UsersBean {
private List<User> allUsers;
public UsersBean() {
init();
}
private void init() {
UsersController.doInitialise(allUsers);
}
// getters, setters
}
public class UsersController {
public static void doInitialise(List<User> users) {
users = new ArrayList<User>();
UserDao userDao = new UserDaoImpl();
users = userDao.getAllEnities();
System.out.println(users.toString());
}
}
public class UserDaoImpl{
#Override
public List<User> getAllEnities() {
List<User> users= null;
Session session = null;
Transaction transaction = null;
try {
session = sessionFactory.openSession();
transaction = session.beginTransaction();
org.hibernate.query.Query query = session.createQuery("from User");
users= query.list();
transaction.commit();
} finally {
session.close();
}
return users;
}
}
If you want to modify the content of the original list, don't assign another list object to it, this will have no effect.
Instead, just alter the content directly, i.e :
public static void doInitialise(List<User> users) {
UserDao userDao = new UserDaoImpl();
users.addAll(userDao.getAllEnities());
System.out.println(users.toString());
}
You are not assigning the value of allUsers into your UsersBean, probably that's why is not working. To have it working, refactor the doInitialise to return a List<User>, then, in the UsersBean, just assign the users.
class UsersBean {
private List<User> allUsers;
public UsersBean() {
init();
}
private void init() {
this.allUsers = UsersController.doInitialise();
}
}
public class UsersController {
public static List<User> doInitialise() {
UserDao userDao = new UserDaoImpl();
return userDao.getAllEnities();
}
}
Related
I have class
public class CloneUserService {
private final UserRepository userRepository;
private final PersonRepository personRepository;
private final OrderRepository orderRepository;
public CloneUserService(UserRepository userRepository, PersonRepository personRepository, OrderRepository orderRepository) {
this.userRepository = userRepository;
this.personRepository = personRepository;
this.orderRepository = orderRepository;
}
public void createFromTemplate(String templateUserId) {
User templateUser = userRepository.getUserById(templateUserId);
Person templatePerson = personRepository.getPersonByUserId(templateUserId);
List<Order> templateOrders = orderRepository.getOrdersByUserId(templateUserId);
User newUser = cloneUserFromTemplate(templateUser);
newUser.setId("newId");
userRepository.save(newUser);
Person newPerson = clonePersonFromTemplate(templatePerson);
newPerson.setUser(newUser);
newPerson.setId("newId");
personRepository.save(newPerson);
for (Order templateOrder : templateOrders) {
Order newOrder = cloneOrderFromTemplate(templateOrder);
newOrder.setId("newId");
newOrder.setUSer(newUser);
orderRepository.save(newOrder);
}
}
private Order cloneOrderFromTemplate(Order templateOrder) {
//logic
return null;
}
private Person clonePersonFromTemplate(Person templatePerson) {
//logic
return null;
}
private User cloneUserFromTemplate(User templateUser) {
//logic
return null;
}
}
I need to test this method createFromTemplate.
I create this test. I create stabs for each repository and store saved object into this stub. And I add the additional method for getting this object for the assertion.
It works. But I have 2 problems:
My template object is mutable. It is not a big problem but it is a fact.
If I add new methods to repository interface I must implement it in stubs.
Mu question - How can I test cloned objects like theses from my example?
I don't use spring and H2DB or another in-memory database.
I have a MongoDB database.
If I use mockito I will not understand how to assert new objects in void method.
class CloneUserServiceTest {
private CloneUserService cloneUserService;
private UserRepositoryStub userRepository;
private PersonRepositoryStub personRepository;
private OrderRepositoryStub orderRepository;
#Before
public void setUp() {
User templateUser = new User();
Person templatePerson = new Person();
List<Order> templateOrders = Collections.singletonList(new Order());
userRepository = new UserRepositoryStub(templateUser);
personRepository = new PersonRepositoryStub(templatePerson);
orderRepository = new OrderRepositoryStub(templateOrders);
cloneUserService = new CloneUserService(userRepository, personRepository, orderRepository);
}
#Test
void createFromTemplate() {
cloneUserService.createFromTemplate("templateUserId");
User newUser = userRepository.getNewUser();
// assert newUser
Person newPerson = personRepository.getNewPerson();
// assert newPerson
Order newOrder = orderRepository.getNewOrder();
// assert newOrder
}
private static class UserRepositoryStub implements UserRepository {
private User templateUser;
private User newUser;
public UserRepositoryStub(User templateUser) {
this.templateUser = templateUser;
}
public User getUserById(String templateUserId) {
return templateUser;
}
public void save(User newUser) {
this.newUser = newUser;
}
public User getNewUser() {
return newUser;
}
}
private static class PersonRepositoryStub implements PersonRepository {
private Person templatePerson;
private Person newPerson;
public PersonRepositoryStub(Person templatePerson) {
this.templatePerson = templatePerson;
}
public Person getPersonByUserId(String templateUserId) {
return templatePerson;
}
public void save(Person newPerson) {
this.newPerson = newPerson;
}
public Person getNewPerson() {
return newPerson;
}
}
private static class OrderRepositoryStub implements OrderRepository {
private List<Order> templateOrders;
private Order newOrder;
public OrderRepositoryStub(List<Order> templateOrders) {
this.templateOrders = templateOrders;
}
public List<Order> getOrdersByUserId(String templateUserId) {
return templateOrders;
}
public void save(Order newOrder) {
this.newOrder = newOrder;
}
public Order getNewOrder() {
return newOrder;
}
}
}
In your scenario I would consider using mocking framework like Mockito.
Some main advantages:
Adding new methods to repository interface doesn't require implementing it in stubs
Supports exact-number-of-times and at-least-once verification
Allows flexible verification in order (e.g: verify in order what you want, not every single interaction)
Very nice and simple annotation syntax - #Mock, #InjectMocks, #Spy
Here is an example - maybe it will interest you:
// arrange
Warehouse mock = Mockito.mock(Warehouse.class);
//act
Order order = new Order(TALISKER, 50);
order.fill(warehouse); // fill will call remove() implicitly
// assert
Mockito.verify(warehouse).remove(TALISKER, 50); // verify that remove() method was actually called
Java 8 here. I am have 2 POJOs:
public class User {
private String id;
private String moniker;
// ... lots of other fields
// Getters & setters down here
}
public class UserDetail {
private String userId;
private String moniker;
// ... lots of other fields
// Getters & setters down here
}
I'm being given a List<User> and a Set<UserDetail>. If there are any UserDetails in that set whose userId fields match any of the User#id values in the user list, I need to update the respective User#moniker with the field of the same name in the UserDetail set.
I have been able to do this the "old" way (pre-Java 8 Stream/Collection APIs) like so:
final List<User> users = userService.fetchSomehow();
final Set<UserDetail> userDetails = userDetailService.fetchSomehow();
for (UserDetail userDetail : userDetails) {
for (User user : users) {
if (userDetail.getUserId().equals(user.getId())) {
user.setMoniker(userDetail.getMoniker());
}
}
}
How could I do this with the Java 8 APIs? That is, how could I loop through both collections, and for any elements with matching IDs, use the moniker value from the UserDetails to update the moniker value in the Users?
performance wise would be better if put userDetails in a map
Map<String, String> userDetailsMap = userDetails.stream()
.collect(Collectors.toMap(UserDetail::getUserId, UserDetail::getMoniker));
users.stream().filter(u -> userDetailsMap.containsKey(u.getId())).forEach(u -> {
u.setMoniker(userDetailsMap.get(u.getId()));
});
Since your userId is dependent with moniker parameter. So, I've implemented using both stream and advance for loop. You can have a glance. Your question is tricky and interesting as well.
Approach One
users.stream().forEach(System.out::println);
userdetails.stream().forEach(userdetail->{
for(User user : users) {
if(user.getId().equals(userdetail.getUserId())){
user.setMoniker(userdetail.getMoniker());
}
}
});
System.out.println("********************");
users.stream().forEach(System.out::println);
Approach Two
public static List<User> users = getUserList();
public static void main(String[] args) {
Set<UserDetail> userdetails = getUserDetails();
users.stream().forEach(System.out::println);
//Note: CompareUpdateList is name of my Class
userdetails.stream().forEach(CompareUpdateList::updateUser);
System.out.println("********************");
users.stream().forEach(System.out::println);
}
public static void updateUser(UserDetail userdetail) {
for(User user : users) {
if(user.getId().equals(userdetail.getUserId())){
user.setMoniker(userdetail.getMoniker());
}
}
}
Third Approach
public static List<User> users = getUserList();
public static void main(String[] args) {
Set<UserDetail> userdetails = getUserDetails();
users.stream().forEach(System.out::println);
//Note: CompareUpdateList is name of my Class
userdetails.stream().forEach(CompareUpdateList::updateUser);
System.out.println("********************");
users.stream().forEach(System.out::println);
}
public static void updateUser(UserDetail userdetail) {
users.stream().forEach(user->{
if(user.getId().equals(userdetail.getUserId())){
user.setMoniker(userdetail.getMoniker());
}
});
}
I'm developing a spring web application with Hibernate. I have faced an error when getting column values from a table to a list. But this error keeps coming. Please help me put. Thanks in advance.
#Repository
#Transactional
public class GetProjectsDaoImpl implements GetProjectsDao {
#Autowired
private HibernateUtilImpl hibernateutilimpl;
public List<Projects> getProjects() {
String sql = "select project_id from project";
List<Object[]> projectObjects = hibernateutilimpl.fetchAll(sql);
List<Projects> projectsList = new ArrayList<Projects>();
for(Object[] projectObject: projectObjects) {
Projects project = new Projects();
String id = (String) projectObject[0];
project.setProjectId(id);
projectsList.add(project);
}
return projectsList;
}
}
#Repository
public class HibernateUtilImpl implements HibernateUtil {
#Autowired
private SessionFactory sessionFactory;
public <T> Serializable create(final T entity) {
return sessionFactory.getCurrentSession().save(entity);
}
public <T> T update(final T entity) {
sessionFactory.getCurrentSession().update(entity);
return entity;
}
public <T> void delete(final T entity) {
sessionFactory.getCurrentSession().delete(entity);
}
#SuppressWarnings("rawtypes")
public <T> List<T> fetchAll(String query) {
return sessionFactory.getCurrentSession().createNativeQuery(query).list();
}
}
I have following suggestions. First change:
List<Object[]> projectObjects = hibernateutilimpl.fetchAll(sql);
to:
List<Object> projectObjects = hibernateutilimpl.fetchAll(sql);
Next, change:
for(Object[] projectObject: projectObjects) {
String id = (String) projectObject[0];
to
for(Object projectObject: projectObjects) {
String id = (String) projectObject;
The above change is needed because you are selecting only a single column. Object[] is used only when selecting more then one column.
I want to use dropdown and getting the value in drop down from database, dropdown should contain company code for saving purpose & company description for display purpose.
Below is my code:
Bean Class:
package com.ims.master.company.bean;
public class CompanyBean {
private String id;
private String cmpCode;
private String cmpDes;
private String cmpStatus;
private String cmpCreated;
public CompanyBean(String cmpCode, String cmpDes) {
super();
this.cmpCode = cmpCode;
this.cmpDes = cmpDes;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCmpCreated() {
return cmpCreated;
}
public void setCmpCreated(String cmpCreated) {
this.cmpCreated = cmpCreated;
}
public String getCmpCode() {
return cmpCode;
}
public void setCmpCode(String cmpCode) {
this.cmpCode = cmpCode;
}
public String getCmpDes() {
return cmpDes;
}
public void setCmpDes(String cmpDes) {
this.cmpDes = cmpDes;
}
public String getCmpStatus() {
return cmpStatus;
}
public void setCmpStatus(String cmpStatus) {
this.cmpStatus = cmpStatus;
}
}
DAO class:
package com.ims.master.company.DAO;
import java.util.ArrayList;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.ims.hibernate.HibernateUtil;
import com.ims.master.company.bean.CompanyBean;
public class CompanyDAO {
SessionFactory factory = HibernateUtil.getFactory();
Session session = factory.openSession();
ArrayList<CompanyBean> recList = new ArrayList<CompanyBean>();
#SuppressWarnings("unchecked")
public ArrayList<CompanyBean> retrieveCmpCode()
{
System.out.println("=====inside DAO======");
Query query = session.createQuery("select b.cmpCode,b.cmpDes from CompanyBean b where b.cmpStatus=:val");
query.setParameter("val", "Y");
recList = (ArrayList<CompanyBean>) query.list();
System.out.println("=====value====="+recList);
return recList;
}
}
Action Class:
package com.ims.master.masterData;
import java.util.ArrayList;
import com.ims.master.company.DAO.CompanyDAO;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
public class MasterLookUp extends ActionSupport {
ArrayList companyCode;
public String getCompany()
{
CompanyDAO companyCodeValue = new CompanyDAO();
companyCode = companyCodeValue.retrieveCmpCode();
return SUCCESS;
}
public ArrayList getCompanyCode() {
return companyCode;
}
public void setCompanyCode(ArrayList companyCode) {
this.companyCode = companyCode;
}
}
jsp:
<s:select name="companyName" list="companyCode" key="label.companyName" listKey="cmpCode" listValue="cmpDes"/>
Please suggest me how the value will come in drop down.
Also suggest that how the value in drop down will be displayed selected in edit part.
You can't cast returned value to ArrayList<CompanyBean>, because Hibernate in your case converts the data returned by the query to List<Object[]>. To return List<CompanyBean> you can use another query.
You need to open the Hibernate session to execute the query, and when you have done with it you should close the session. You don't have to close a session only if it's managed by other tool. You can find a detailed explanation how to use Hibernate session in How to display a list of database records (retrieved via Hibernate) to a JSP page in Struts 2, and linked answer.
The query could return List<CompanyBean> if you change the query and property type, so you can assign a value without casting.
public class CompanyDAO {
public List<CompanyBean> retrieveCmpCode() throws Exception
{
System.out.println("=====inside DAO======");
SessionFactory factory = HibernateUtil.getFactory();
Session session = factory.openSession();
List<CompanyBean> recList;
try {
Query query = session.createQuery("from CompanyBean b where b.cmpStatus=:val");
query.setParameter("val", "Y");
recList = query.list();
System.out.println("=====value====="+recList);
return recList;
} finally {
session.close();
}
}
}
Note: #SuppressWarnings("unchecked") no longer needed.
In the JSP you should bind the select tag to the action property that returns a List<CompanyBean>, similar like you have done already.
<s:select name="companyName" list="companyCode" key="label.companyName" listKey="cmpCode" listValue="cmpDes"/>
The action
public class MasterLookUp extends ActionSupport {
private List<CompanyBean> companyCode;
public List<CompanyBean> getCompanyCode() {
return companyCode;
}
public void setCompanyCode(List<CompanyBean> companyCode) {
this.companyCode = companyCode;
}
private String cmpCode;
public String getCmpCode() {
return cmpCode;
}
public void setCmpCode(String companyCode) {
this.cmpCode = cmpCode;
}
public String getCompany() throws Exception
{
CompanyDAO companyCodeValue = new CompanyDAO();
companyCode = companyCodeValue.retrieveCmpCode();
return SUCCESS;
}
}
Note: to get/set default/selected value of the select tag you should provide cmpCode property.
you can use below code in your JSP
<html:select property ="cmpDes">
<html:optionsCollection name ="cmpDes" />
</html:select>
When above code is added in ur JSP , your dropdown will have the cmp description which is fetched from DB.
And below is site which has perfect example to learn struts-1 and is also related to your question for getting some ideas to go on.
http://www.javabeat.net/struts-html-optionscollection-tag-htmloptionscollection/
I am using eclipse-link, and I am retrieving data from table and trying to store the retrieved data into XML file using JAXB. While writing into XML file last record only saved in that file.
Here User is My POJO class have Two fields
#XmlRootElement
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
#XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User()
{
}
}
Below is My code:
public class ObjectToXml {
private static int startingIndex = 0;
private static int maxIndex= 10;
public static void main(String[] args) {
EntityManager entityManager = EntityManagerUtil.getEmf()
.createEntityManager();
Query query = entityManager.createQuery("Select u from User u");
System.out.println("Total Number of Records"
+ query.getResultList().size());
try {
JAXBContext contextObj = JAXBContext.newInstance(User.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
query.setFirstResult(startingIndex );
query.setMaxResults(maxIndex);
List<User> user = query.getResultList();
Iterator iterator = user.iterator();
while (iterator.hasNext()) {
User student = (User) iterator.next();
MarshallerObj.marshal(student, new FileOutputStream("User.xml"));
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
entityManager.close();
}
}
}
Here i am getting 10 records.But while storing last Record only saved in XML
My Result :
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<user id="10">
<name>prabha</name>
</user>
Because MarshallerObj.marshal(student, new FileOutputStream("User.xml")); creating new file o/p stream everytime and that clears prev contents. create this instance of o/p stream out of your while loop. that should help.
Perhaps you should keep one single FileOutputStream and marshall continuously into it instead of creating a new one on every iteration.
Since you are creating xml file for each User object, the objects will be keep on replacing when the program is taking an new User from DB
So create a POJO class Users with List of User as an attribute,
public class Users
{
//Users grouping
private List<User> user;
public void setUser(List<ProductInfo> userInfo)
{
this.user = userInfo;
}
#XmlElement(name="user")
public List<User> getUser() {
return user;
}
}
Then in the code section create instance of JAXBContext for the class Users, like mentioned below
JAXBContext contextObj = JAXBContext.newInstance(Users.class);
Now modify the while loop to set all user's information into Users object, and marshar the Users object than marshaling the User object.
Users users = new Users();
while (iterator.hasNext()) {
User student = (User) iterator.next();
users.setUser(student);
}
MarshallerObj.marshal(users, new FileOutputStream("User.xml"));
You will need to use #XmlElements annotation.
Marshaller.marshal() simply converts the object into byte stream and writes into output stream. Hence it will override the existing data in ouputstream. In your case, since marshallerObj.marshal(student, new FileOutputStream("User.xml")); is inside a loop, the final file would always contain the last object in the list. I.e in the first iteration it will write first object to the file, in second iteration it will overwrite the file with second object, in third iteration it will overwrite the file with third object and so on.
To marshal a list of objects, one of the solution is to create a container object which will maintain a list of all users/students and then marshal the container object.
Refer to link for similar question.
In your case the container class should look something like:
#XmlRootElement(name = "Users")
public class Users
{
private List<User> users = new ArrayList<User>();
#XmlElements(value = {#XmlElement(name = "User", type = User.class)})
#XmlElementWrapper
public List<User> getUsers() {
return users;
}
public void addUser(User user) {
users.add(user);
}
}
And the code to marshal the Users:
Users users = new Users();
List<User> usersList = query.getResultList();
for(User user : usersList) {
users.addUser(user);
}
marshallerObj.marshal(users, new FileOutputStream("User.xml"));