Combining xml and java configurations in spring 3.2 + hibernate 4 - spring

I get the following error when i try to manipulate the person 'entity' from within the spring container:
Exception in thread "main" org.hibernate.MappingException: Unknown entity: org.s
pring.entity.Person
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionF
actoryImpl.java:1141)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.jav
a:1433)
Where am I going wrong - perhaps in trying to combine the xml and annotated metadata?
Appreciate any help on this.
Entity:
#Entity
#Table(name = "PERSON")
public class Person implements Serializable {
private static final long serialVersionUID = -5527566248002296042L;
#Id
#Column(name = "ID")
#GeneratedValue
private Integer id;
#Column(name = "FIRST_NAME")
private String firstName;
#Column(name = "LAST_NAME")
private String lastName;
.....
.....
}
Service bean:
#Service("personService")
#Transactional
public class PersonService {
#Resource(name="sessionFactory")
private SessionFactory sessionFactory;
public List<Person> getAll() {
// Retrieve session from Hibernate
Session session = sessionFactory.openSession();
try{
// Create a Hibernate query (HQL)
Query query = session.createQuery("FROM Person");
// Retrieve all
return query.list();
}
finally{
session.close();
}
}
....
....
}
Main:
public static void main(String[] args){
ApplicationContext appContext =
new ClassPathXmlApplicationContext("META-INF/beans-txn.xml");
PersonService personService = (PersonService)appContext.getBean("personService");
personService.add("Rob","Cahill", new Double(20000));
List<Person> persons = personService.getAll();
.....
spring configuration:
<context:annotation-config />
<bean id="personService" class="org.spring.service.PersonService"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
.....
</bean>
<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
.....
</property>
</bean>

Add to your sessionFactory bean definition:
<property name="packagesToScan" value="common.**.entities" />
Where common.**.entities - package with your entities.

Related

hibernate JPA error : org.hibernate.hql.internal.ast.QuerySyntaxException: users is not mapped

Hi i am learning to write spring web application and i get this error:
org.hibernate.hql.internal.ast.QuerySyntaxException: users is not mapped [SELECT u FROM users u WHERE u.username = :username AND u.password = :password]]
can someone help me fix this table not mapped issue:
my JPA configuration class
#Configuration
public class JpaConfig {
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
emfb.setPersistenceXmlLocation("classpath:META-INF/persistence.xml");
emfb.afterPropertiesSet();
return emfb.getObject();
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://localhost:5432/schoolDB");
ds.setUsername("postgres");
ds.setPassword("******");
return ds;
}
}
my model class
#Entity
#Table(name ="users")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
private Integer id;
#Column(name="username")
private String username;
#Column(name="password")
private String password;
public String getUsername() {
return username;
}
repository configuration
#Repository
public class UserRepository {
#PersistenceUnit(unitName = "myschool")
private EntityManagerFactory emf;
private static Logger logger = LoggerFactory.getLogger(UserRepository.class);
public User checkUser(String username, String password) {
logger.info("********** User Repository ********");
try {
EntityManager em = emf.createEntityManager();
TypedQuery<User> typedQuery = em.createQuery("SELECT u FROM users u WHERE u.username = :username AND u.password = :password", User.class);
typedQuery.setParameter("username", username);
typedQuery.setParameter("password", password);
return typedQuery.getSingleResult();
} catch (NoResultException nre) {
logger.info("********** User Repository Exception ********");
return null;
}
}
}
my persistence.xml
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="myschool">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/schoolDB" />
<property name="javax.persistence.jdbc.user" value="postgres" />
<property name="javax.persistence.jdbc.password" value="******" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
<property name="hibernate.hbm2ddl.auto" value="update"/> <!-- update -->
<property name="hibernate.show_sql" value="true"/> <!-- Show SQL in console -->
<property name="hibernate.format_sql" value="true"/> <!-- Show SQL formatted -->
</properties>
org.hibernate.hql.internal.ast.QuerySyntaxException: users is not
mapped
createQuery used to create JPQL. In JPQL, you should use the name of the Entity class instead of the name of the table. So use User instead of users in query
em.createQuery("SELECT u FROM User u WHERE u.username = :username AND u.password = :password", User.class);

Bean variable not loading during unit test

I am trying to test some dao code in Spring Boot. Here is my class under test:
#Repository
public class AreaDao
{
#Setter private JdbcTemplate jdbcTemplate;
#Setter private AreaMapper areaMapper;
#Getter #Setter private String sql;
public List getArea(String studioId)
{
String query = String.join(this.getSql(),studioId); // its throwing a NPE here
List areaList = jdbcTemplate.query(query, areaMapper);
return areaList;
}
}
The variable sql is loading from the bean xml:
<bean id="AreaDao" class="com.studio.dao.AreaDao">
<property name="sql" value="SELECT DISTINCT(rGrp.GRP_N) AS AreaName
FROM DB.S_GRP rGrp
WHERE rGrp.STR_I = " />
<property name="jdbcTemplate" ref="JdbcTemplate" />
<property name="areaMapper" ref="AreaMapper" />
</bean>
<bean id="AreaMapper" class="com.studio.mapper.AreaMapper" />
<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="DMDataSource" />
</bean>
And here is my test class:
#RunWith(SpringRunner.class)
#SpringBootTest
public class AreaDaoTest {
#Mock
JdbcTemplate jdbcTemplateMock;
#Mock
AreaMapper areaMapper;
#InjectMocks
#Spy
AreaDao areaDao;
private List areas;
#Before
public void setup(){
areas = new ArrayList();
}
#Test
public void testGetArea() throws SQLException {
String studioId = "12345";
when(jdbcTemplateMock.query(any(String.class), any(RowMapper.class))).thenReturn(areas);
List areas = areaDao.getArea(studioId);
Assert.assertNotNull(areas);
Assert.assertTrue(areaDao.getSql().contains(studioId));
}
}
Whenever I try to run the test its throwing a NPE in loading the sql var from the bean xml. I tried adding #ContextConfiguration or just #Autowired on the dao in the test but it didn't work. Also how can I verify in the test if its loading a value?
Appreciate your help.

Why is my #Autowired field null here?

This is not a duplicate of this question. So please don't close it for "is duplicate of" reasons..
I am trying to autowire a private field in my service class using this tutorial. My problem is that restaurantOwnerRepository remains null and does not get initialized.
servlet-context.xml
<context:component-scan base-package="com.mahlzeit.web.server" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="restaurantOwnerRepository" class="com.mahlzeit.web.server.dao.RestaurantOwnerRepository">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
Service code:
#Component
public class RestaurantInformationServiceImpl extends XsrfProtectedServiceServlet implements RestaurantInformationService {
private static final long serialVersionUID = -4088840947018614411L;
#Autowired
private RestaurantOwnerRepository restaurantOwnerRepository;
private final static Logger logger = Logger.getLogger(RestaurantInformationServiceImpl.class);
#Override
public List<RestaurantDTO> getAvailableRestaurants() {
// restaurantOwnerRepository is 'null'
List<Restaurant> availableRestaurants = restaurantOwnerRepository.getAvailableRestaurants(getSessionId());
return null;
}
private String getSessionId() {
HttpServletRequest httpRequest = getThreadLocalRequest();
return httpRequest.getSession().getId();
}
}
RestaurantOwnerRepository.java
public class RestaurantOwnerRepository implements RestauranOwnerDAO {
private SessionFactory sessionFactory;
public RestaurantOwnerRepository(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// ..
}
What could be the reason for this?
here is a sample controller for your example , you should define the bean in your context.xml or if you place it in this package : com.mahlzeit.web.server it will be managed by spring automatically , cause as i see you have placed the context:component-scan
#Controller
public class RestaurantInformationServiceImpl {
#Autowired
private RestaurantOwnerRepository restaurantOwnerRepository;
#RequestMapping(value="/")
public #ResponseBody ModelAndView getRestaurants(
HttpServletRequest request,
HttpServletResponse response) {
ModelAndView model = new ModelAndView("yourPage");
List<?> rests = restaurantOwnerRepository.getAvailableRestaurants(httpRequest.getSession().getId());
model.addObject("restList", rests );
return model;
}
}

Annotation #Transactional does not working

I am trying to use the annotation #Transactional to access my MySQL using Hibernate, Spring and JSF. My problem is:
When I use the annotation #Transactional at my managedBean to make a query I got this error:
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:65)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
at br.com.rpg.DAO.AbstractDAO.getCurrentSession(AbstractDAO.java:14)
at br.com.rpg.DAO.CountryDAO.findAll(CountryDAO.java:14)
at br.com.rpg.managedBeans.SignupBean.init(SignupBean.java:45)
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)
I don't know what I'm doing wrong. My code and xml config is:
application-config.xml
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="br.com.rpg.DO" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<context:component-scan base-package="br.com.rpg" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
My MB
#Named
#Scope("request")
public class SignupBean implements Serializable {
private static final long serialVersionUID = 1787096549063029840L;
#Inject
private CountryDAO country;
#Inject
private UserDAO user;
private Map<String, Integer> countries;
private Integer selected;
private String username;
private String password;
#PostConstruct
#Transactional
public void init() {
List<CountryDO> findAll = country.findAll();
countries = new HashMap<String, Integer>();
for (CountryDO countryDO : findAll) {
countries.put(countryDO.getName(), countryDO.getId());
}
}
public Map<String, Integer> getCountries() {
return countries;
}
public void setCountries(Map<String, Integer> countries) {
this.countries = countries;
}
public Integer getSelected() {
return selected;
}
public void setSelected(Integer selected) {
this.selected = selected;
}
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;
}
My Country DAO has the #Named annotation. Someone could help me?
Thx.
you have applied #PostConstruct and #Transactional on init method. init method would be called before applying any AOP Proxy interceptor is applied because of #PostConstruct. Hence at the time of invoking init there is no transaction proxy applied. if you need to call init method on Application startup use ApplicationEvent

JPA - Entities are not stored in database

I am facing a problem, when I tried to insert a data into Database through JPA (#persistanceContex)
Observations
Not getting any errors;
Record is not storing into database (save)
When I tried with listAll() ; it retrieving the data from database
Domain
#Entity
public class Test {
#Id
private int id;
#Column(name="full_name")
private String fullName;
#Column(name="mobile_number")
private int mobileNumber;
.....
}
DAO Class
#Repository("testDAO")
#Transactional
public class TestDAO {
private EntityManager entityManager;
#PersistenceContext(unitName="CRUD_Test_Annotation")
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void save(Test test){
entityManager.persist(test);
}
}
Service
#Service("testService")
#Transactional
public class TestService {
private static final Logger logger = LoggerFactory.getLogger(TestService.class);
#Autowired(required=true)
private TestDAO testDAO;
public void save(Test test){
logger.info("TestService::save()");
testDAO.save(test);
}
public void list(){
testDAO.getAll();
}
}
Controller
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(Locale locale, Model model) {
Test test = new Test();
test.setId(xx);
test.setFullName("xxxxx");
test.setMobileNumber(yyyyyy);
testService.save(test);
return "home";
}
application-context.xml
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Declare a JPA entityManagerFactory-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="CRUD_Test_Annotation" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
First of all, you don't need two transaction boundaries, I suggest you remove #Transactional from your DAO and keep the one in your service.
Start by verifying that spring-transaction has initiated a transaction: Use the debugger and stop the application after the transaction boundary, for instance in your TestService.save-method. If transactions are running, you will see org.springframework.transaction.interceptor.TransactionInterceptor#invoke in the call stack. If you don't see the TransactionInterceptor, then that's your problem. Post your persistence.xml file if transactions are running.

Resources