I am implementing a simple application to do CRUD operations, using Spring framework.
Source code:
User.java is the model class.
package com.vipin.model;
public class User {
private int ssn;
private String firstName;
private String lastName;
private String emailId;
public int getSsn() {
return ssn;
}
public void setSsn(int ssn) {
this.ssn = ssn;
}
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 getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
Dao layer:
package com.vipin.dao;
import com.vipin.model.User;
public interface DBOpsDao {
boolean add(User user);
boolean find(int ssnId);
}
The class which implements (skelton) implementation is:
package com.vipin.dao;
import java.sql.Connection;
import java.sql.SQLException;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.vipin.model.User;
public class DefaultDBOpsDaoImpl implements DBOpsDao {
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
#Resource(name="dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
System.out.println("Datasource value is " + dataSource);
}
public boolean add(User user) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
return false;
}
public boolean find(int ssnId) {
// TODO Auto-generated method stub
return false;
}
}
Sample Main class:
package com.vipin.app;
import com.vipin.dao.DBOpsDao;
import com.vipin.dao.DefaultDBOpsDaoImpl;
import com.vipin.model.User;
public class MainApp {
public static void main(String[] args) {
System.out.println("Inside main...");
DBOpsDao dao = new DefaultDBOpsDaoImpl();
User user = new User();
user.setFirstName("xxx");
user.setLastName("yyy");
user.setSsn(1);
user.setEmailId("xxx.yyy#example.com");
dao.add(user);
}
}
I am using maven to build this, so the java source code is in:
src/main/java (top level package com.vipin)
When i run this program it is throwing exception complaining that spring.xml doesn't exist. I
used ApplicationContext, one of implementation ClassPathXmlApplicationContext.
In which location do i need to put spring.xml file?
Any inputs would be helpful.
You will need to add spring.xml file at the location - src/main/resources folder. You can have your directory structure inside this directory as - src/main/resources/com/vipin/dao.
src/main/java directory is preferred for java classes.
If you are debugging from eclipse, make sure that you are adding your folder in the project's classpath.
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
If you create your maven project using maven archetype and you import into eclipse, you need to edit your .classpath file.
You have to initilalize application context properly in your main method. You can check this link for example.
Place the xml file at the root of your classpath
For maven that is src/main/resources/ if the directory doesn't exist yet, create it.
src/main/resources/applicationContext.xml
Also src/main/resources/spring/ works as well.
Related
I am running a simple Maven Java EE web project on Payara
I am trying demonstrate the working of Interceptor but it isn't getting called. I have even defined it in a beans.xml file
Payara Version: 5.184
Edition: Full
JDK Version: 1.8, Java EE 7
Operating System: Mac
Database: Oracle
Bean class
package com.maven.web;
import com.interceptors.LogNameInterceptor;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.faces.bean.ManagedBean;
import javax.interceptor.Interceptors;
#ManagedBean
#Stateless
public class UserBean implements User {
private String firstName;
private String lastName;
public static final Logger LOGGER = Logger.getLogger(UserBean.class.getName());
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;
}
#Override
#Interceptors(LogNameInterceptor.class)
public String show(String fn, String ln) {
LOGGER.log(Level.INFO, "Inside method");
return "result";
}
}
User.java
package com.maven.web;
import javax.ejb.Remote;
#Remote
public interface User {
public String show(String a, String b);
}
Interceptor class
package com.interceptors;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
#Interceptor
public class LogNameInterceptor {
public static final Logger LOGGER = Logger.getLogger(LogNameInterceptor.class.getName());
#AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
LOGGER.log(Level.INFO, "Inside Interceptor");
System.out.println(ctx.getMethod());
return ctx.proceed();
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.interceptors.LogNameInterceptor</class>
</interceptors>
</beans>
Only 'Inside method' is printed in the log, meaning it doesn't reach the aroundInvoke method
Thanks a lot!
I have problem with my Spring project. I just started with Spring Boot and i try to make ez controller which redirect me to another web.
When i started my application and go to browser on
localhost:8080/person
there is problem with mapping idk why
enter image description here
This is my structure
enter image description here
PersonController
package Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import Model.Person;
public class PersonController {
#RequestMapping("/person")
public String person(Model model)
{
Person p = new Person();
p.setFirstName("John");
p.setLastName("BonJovi");
p.setAge(23);
model.addAttribute("person", p);
return "personview";
}
}
Person Class
package Model;
public class Person {
String firstName;
String lastName;
int age;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
And "Main"
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#Configuration
#EnableAutoConfiguration
#ComponentScan({"demo","controller"})
public class EducationProjectApplication {
public static void main(String[] args) {
SpringApplication.run(EducationProjectApplication.class, args);
}
}
Add a #Controller to the top of your PersonController
Also - just check, your #ComponentScan({"demo","controller"})
"controller" is not capitalized, but your package is declared "Controller"
You must annotated your PersonController class as #RestController.
Like Rafael said you need to put annotations above PersonController class. #RestController if you want to build a REST controller, #Controller if you want to build normal website. Make sure you already configure your view resolver so it will return a jsp files.
I've developed a simple web application which connects to MySQL through hibernate. At a point, I was even successful in creating a connection and inserting the java object in the DB. However, I did some changes thereafter to meet my project needs and there I messed up the things. I am receiving this error "No identifier specified for entity" no matter how much I try to debug it. I even created a new project from scratch but in vain. Please help me out here in identifying what I am doing wrong.
package com.proj.beandb;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
#ManagedBean
#SessionScoped
#Entity
#Table(name="dbstat")
public class Hibernate
{
#Id
#Column(name="first_name")
private static String fname;
#Column(name="last_name")
private static String lname;
public Hibernate(){}
public Hibernate(String fname, String lname)
{
Hibernate.fname = fname;
Hibernate.lname = lname;
}
public static void main(String[] args) {
// create session factory
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(Student.class)
.buildSessionFactory();
// create session
Session session = factory.getCurrentSession();
try {
// create a student object
System.out.println("Creating new object");
Hibernate tempRec = new Hibernate("bah", "blah");
// start a transaction
session.beginTransaction();
// save the object
session.save(tempRec);
// commit transaction
session.getTransaction().commit();
System.out.println("Done!");
}
finally {
factory.close();
}
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
Hibernate.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
Hibernate.lname = lname;
}
}
`
It is a really a big mistake to use static fields as properties of a persistent class.
#Id
#Column(name="first_name")
private static String fname;
#Column(name="last_name")
private static String lname;
should be
#Id
#Column(name="first_name")
private String fname;
#Column(name="last_name")
private String lname;
You don't need it, because of it is not a Hibernate related stuff
#ManagedBean
#SessionScoped
You add Student class with addAnnotatedClass(Student.class), maybe you need to add Hibernate class instead.
And please don't put main() in the persistent class. You need to have Hibernate class and, for an example, HibernateTest class with main().
here is my entity
#Entity
public class User {
#Id
private String id;
private String externalUserId;
private String email;
private String clientId;
private String clientSecret;
private boolean active;
public User(#Nonnull final String externalUserId, #Nonnull final String email,
#Nonnull final String clientId, #Nonnull final String clientSecret, final boolean active) {
id = UUID.randomUUID().toString();
this.externalUserId = externalUserId;
this.email = email;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.active = active;
}
}
and a UserService
import javax.annotation.Nonnull;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
#Stateless
public class UserService {
#PersistenceUnit
private EntityManager entityManager;
#Nonnull
public User createUser(#Nonnull final User user) {
entityManager.persist(user);
return user;
}
}
I also have DBConfig as
import javax.annotation.sql.DataSourceDefinition;
import javax.ejb.Stateless;
#DataSourceDefinition(
name = "java:app/oauth/testDB",
className = "org.h2.jdbcx.JdbcDataSource",
url = "jdbc:h2:mem:test"
)
#Stateless
public class DBConfig {
}
test/src/main/resources/persistence.xml as
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="testDB" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.self.oauth.persistence.entities.User</class>
</persistence-unit>
</persistence>
My test looks like
public class UserTest {
#Inject
private UserService userService;
#Test
public void testUser() {
final User user = new User(UUID.randomUUID().toString(), "test#test.com", "clientId", "clientSecret", true);
userService.createUser(user);
assertTrue(true);
}
}
and I get NullPointeException on userService
What am I missing?
Injection is handled by a Java EE Container in execution time. In particular and checking your piece of code, an EJB container would handle the injection of UserService since it is declared to be a Stateless bean. When you deploy your entire application a container is set and injection works fine. When executing unit tests (I guess using junit) none of the services are launched, and any #Injection will end up with the variable set to null, because no container will be launched either.
The idea is that unit tests should be only used for testing pieces of code independently of external ones like the one contained in other classes. However, in your case it looks like you want an integration test, so, you really need all services to be up since you want to check that an object is persisted in the database. For that, you need you need to launch also a container. A good way of doing that, is using Arquillian.
For instance, in your case, the test should be something like this:
package org.arquillian.example;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(Arquillian.class)
public class UserTest{
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(UserService.class)
.addClass(User.class)
.addClass(DBConfig.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
#Inject
private UserService userService;
#Test
public void testUser() {
final User user = new User(UUID.randomUUID().toString(), "test#test.com", "clientId", "clientSecret", true);
userService.createUser(user);
assertTrue(true);
}
}
I am using Eclipse and Derby database (with Embeeded Driver). As a starting point I am running the asadmin (from glassfish) to start-database from there. The database within eclipse can be pinged, as well as connected to just fine. Having started my EJB project which combines the session beans and entity beans I have ran into the following exception - java.lang.IllegalArgumentException: Unknown entity bean class: class model.Userbay, please verify that this class has been marked with the #Entity annotation.
Just few lines below this error i get pointed to this line of code - Userbay user = emgr.find(model.Userbay.class, username);
Although my feeling is that it could be a problem with the persistence.xml that causes it in the first place.
I would really appreciate any hints/help given towards fixing this annoying problem me and my friend are facing for quite a time now..
The following are the java/xml files;
Persistence.xml (which is stored under ejbModule/META-INF)
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="EJBAuctionv2">
<class>model.Userbay</class>
<class>model.Item</class>
<class>model.Category</class>
</persistence-unit>
</persistence>
I've also tried adding the following properties tag - however it grants another error org.apache.derby.client.am.SqlException: Schema 'ADRIAN' does not exist
<properties>
<property name="javax.persistence.jdbc.password" value="test" />
<property name="javax.persistence.jdbc.user" value="adrian" />
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeededDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:C:/Users/Adrian/MyDB;create=true" />
</properties>
userRegistrationSB.java (Session Bean)
package auction;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Remote;
import javax.ejb.Singleton;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import model.Userbay;
/**
* Session Bean implementation class userRegistrationSB
*/
#Remote #Stateless
public class userRegistrationSB implements userRegistrationSBRemote {
//#EJB private Userbay user;
#PersistenceContext private EntityManager emgr;
/**
* Default constructor.
*/
public userRegistrationSB() {
// TODO Auto-generated constructor stub
System.out.println("TEST2");
}
#Override
public boolean registerUser(String username, String password, String email,
String firstname, String lastname) {
boolean registered = false;
System.out.println("Registering an user");
Userbay user = emgr.find(model.Userbay.class, username);
if (user != null) {
System.out.println("Username doesn't exist.");
registered = true;
} else {
registered = false;
System.out.println("Username already exists.");
}
return registered;
}
#Override
public boolean userExists(String username) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean userMatchesPassword(String username, String password) {
// TODO Auto-generated method stub
return false;
}
}
Userbay.java (Entity Bean)
package model;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
#Entity #Table (name = "Userbay")
/*#NamedQuery(name="Userbay.findAll", query="SELECT u FROM Userbay u")*/
public class Userbay implements Serializable {
private static final long serialVersionUID = 1L;
#Id #Column(name="USER_NAME")
private String userName;
private String email;
#Column(name="FIRST_NAME")
private String firstName;
#Column(name="LAST_NAME")
private String lastName;
#Column(name="PASSWORD")
private String password;
//bi-directional many-to-one association to Item
#OneToMany(mappedBy="userbay")
private List<Item> items;
public Userbay() {
}
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Item> getItems() {
return this.items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public Item addItem(Item item) {
getItems().add(item);
item.setUserbay(this);
return item;
}
public Item removeItem(Item item) {
getItems().remove(item);
item.setUserbay(null);
return item;
}
}
I've also tried adding the following properties tag - however it
grants another error org.apache.derby.client.am.SqlException: Schema
'ADRIAN' does not exist
Have you checked if your database schema was actually created? If it did not, adding the following lines in your persistence.xml might help.
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
You may also want to undeploy your application manually or if it is your developer machine and this is the only application deployed merely delete content of the applications directory in your domain.