How to configure persistance.xml file in SpringBoot project - spring-boot

I created one spring boot application. When I run this I am getting below error for persiatance.xml.
Seems like it is not reading my persistance.xml file. Could you please help me in resolving the issue.
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named EmployeeData
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at com.JPAproject.Entity.InsertEmployee.main(InsertEmployee.java:11)
Below are the related file for reference:
Entity class
package com.JPAproject.Entity;
import javax.persistence.Entity;
import javax.persistence.Table;
#Entity
#Table(name="Employee_JPA")
public class Employee_EntityManager {
private String e_id;
private String e_name;
private Integer e_age;
public String getE_id() {
return e_id;
}
public void setE_id(String e_id) {
this.e_id = e_id;
}
public String getE_name() {
return e_name;
}
public void setE_name(String e_name) {
this.e_name = e_name;
}
public Integer getE_age() {
return e_age;
}
public void setE_age(Integer e_age) {
this.e_age = e_age;
}
public Employee_EntityManager(String e_id, String e_name, Integer e_age) {
super();
this.e_id = e_id;
this.e_name = e_name;
this.e_age = e_age;
}
public Employee_EntityManager() {
super();
}
}
Persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 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_1.xsd">
<persistence-unit name="EmployeeData" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.JPAproject.Employee_EntityManager</class>
</persistence-unit>
</persistence>

The org.hibernate.ejb.HibernatePersistence class has been deprecated for a long time, but you still find it in old tutorials. You need to use the new one org.hibernate.jpa.HibernatePersistenceProvider.
You also don't seem to have a data source, if that is your full XML file, and not a reduced version, so that you don't post passwords and such.

Related

Spring cache EhCache | Data are not updated and deleted from cache

I start to learn Spring Cache abstraction.
I use Spring boot, Spring Data Jpa, EhCache provider for this purpose.
My ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ehcache>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache maxElementsInMemory="100"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true">
</defaultCache>
<cache name="teams"
maxElementsInMemory="500"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="100"
overflowToDisk="false">
</cache>
My service:
#CacheConfig(cacheNames = "teams")
#Service
public class TeamService {
#Autowired
private TeamRepository teamRepository;
#Cacheable
public Team findById(long id) {
return teamRepository.findById(id).get();
}
#Cacheable
public List<Team> findAll() {
return teamRepository.findAll();
}
#CachePut
public Team save(Team team) {
return teamRepository.save(team);
}
#CacheEvict
public void delete(long id) {
teamRepository.deleteById(id);
}
}
My controller:
#RestController
public class TeamController {
#Autowired
private TeamService teamService;
#GetMapping("/teams")
public List<Team> getAll() {
return teamService.findAll();
}
#GetMapping("/team/{id}")
public Team getById(#PathVariable long id) {
return teamService.findById(id);
}
#DeleteMapping("/team/{id}")
public void delete(#PathVariable long id) {
teamService.delete(id);
}
#PostMapping("/team")
public Team save(#RequestBody Team team) {
return teamService.save(team);
}
}
I am performing requests to my controller...
When I perform getAll() method of the controller data are cached correctly and then don't exucute query to database at next times. Then I update and delete data from the database using corresponding methods of my controller, which service methods are marked as #CachePut and #CacheEvict respectively and must refresh cache. Then I perform above getAll() method again and get the same response like at the first time but I want that it will be refreshed after performing delete and update requests.
What's I doing wrong or How I can get the desired result?.
When you put #Cachable annotation on a method so all entries will be kept on cache added by default a name then the first cachable is different to second cachable, so if you want to work well you need to add a name that you want, for example:
#Cachable("teams")
#Cachable("teams")
#CachePut("teams")
#CacheEvict(value="teams", allEntries=true)
You can get more information in this link: https://www.baeldung.com/spring-cache-tutorial
Perhaps a best solution would be this:
#Cachable("team")
#Cachable("teams")
#Caching(put = {
#CachePut(value="team"),
#CachePut(value="teams") })
#Caching(evict = {
#CacheEvict(value="team", allEntries=true),
#CacheEvict(value="teams", allEntries=true) })

Spring Advice On Setter Not Triggered

i have this below code .
advice on setter is not triggered even though setter is called.
i can see it in the console
if i do advice on String getName() everything works just fine.
but its not working on setter public void setName(String name).
spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:aspectj-autoproxy />
<bean id="cust" class="aspectJ.Customer">
<property name="name" value="logging" />
</bean>
<bean id="aspect" class="aspectJ.LoggingAspect"/>
</beans>
Logging ASPECT
#Aspect
public class LoggingAspect {
#Before("allgetters()")
public void printAspect() {
System.out.println("Aspect Running");
}
#Before("allgetters()")
public void printAspectTwo() {
System.out.println("Aspect TWO Running");
}
#Pointcut("execution(public void setName(*))")
public void allgetters() {
}
}
CUSTOMER CLASS
package aspectJ;
public class Customer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("SETTER CALLED");
}
}
Main Class
public class MainClass {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Customer obj = (Customer) context.getBean("cust");
}
}
Your aspect signature is wrong.
* will match a singular field
.. will match zero or multiple fields
Example 1
com.stackoverflow.*.Customer.setName(..)
Matches all packages starting with com.stackoverflow and ending with Customer. The wildcard will only match one package name. The method can accept zero or more arguments. Below are three examples of what it will match:
com.stackoverflow.question.Customer.setName()
com.stackoverflow.question.Customer.setName(String arg1)
com.stackoverflow.question.Customer.setName(String arg1, String arg2)
Example 2
com..Customer.setName(*, *)
Match all packages starting with com and ending with Customer. Accept methods with two arguments of any type. Below are two examples of what it will match. Notice that the wildcard will accept any number of packages.
com.example.Customer.setName(String arg1, Object arg2)
com.stackoverflow.question.Customer.setName(Integer arg1, Double arg2)
You should change your allgetters() to the following:
#Pointcut("execution(public void setName(..))")
public void allgetters() {
}
Spring AOP only works with beans managed by Spring. A bean is not managed until it is initialized, regardless if it is defined in Java or XML.
//The Customer object returned by this method is managed.
//The Customer object within the method is not managed
#Bean
public Customer createCustomer(){
//This is a pure Java object
Customer customer = new Customer();
//The object is not yet managed. This method call will therefore never be intercepted by your Pointcut.
customer.setName(“John Doe”);
return customer;
}
Quote from the documentation:
Spring AOP only supports method execution join points for Spring
beans, so you can think of a pointcut as matching the execution of
methods on Spring beans.
Just Posting what user #javamusings said :
The advice is called only when the setter is called in the Java class. It is not called when the property is initialized in the aspectj.xml

spring ehcache is not working

I am trying to implement ehcache to get static data (from table) loaded during application startup however when I make a call again to database, the call is going to database (can see running sql on console) instead of taking values from ehcache.
my code is:
ehcache.xml as below:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="ObjectList"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="2000000" timeToLiveSeconds="900000000000"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
my repository class is:
public interface customRepository extends JpaRepository<Object, Long> {
#Cacheable(value = "ObjectList", cacheManager="abclCacheManager")
public Object findById(Long id);
#Cacheable(value = "ObjectList", cacheManager="abclCacheManager")
public List<Object> findAll();
}
and my cacheInitialiser class is:
#Configuration
#EnableCaching
#ComponentScan("com.abcl.process")
public class EhCacheConfiguration {
#Bean("abclCacheManager")
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
#Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
cmfb.setShared(true);
cmfb.setCacheManagerName("abclCacheManager");
return cmfb;
}
}
I am testing my this using below:
public class testCache {
doSomething() {
List<Object> listObject = repo.findAll();
listObject.size();
}
public void getOne() {
Object o = repo.findById(1L);
}
}
I can see a db hit in getAll method however I thought the results would get stored in cache and in the second call there would not be a db hit by method getById however I see a db hit on second call as well.
Can anyone please suggest if I am missing anything here.
When you cache the results of findAll it creates a single entry in the cache which maps the key generated by Spring caching, since your method has no parameter, to the List<Object>. It does not put into the cache one mapping per list element between id and the Object.
So when you use findById(Long), Spring caching will look for a cache entry mapping to the id. And since it cannot find one, it will hit the database.
There is no way of having Spring caching put one mapping per collection element. If that is really what you need, you will have to code it instead of relying on the #Cacheable annotation.

EasyMock on Spring jdbcTemplate is always returning null rather mocked object

I'm trying to use EasyMock 3.4 on a Java Spring project. I have successfully mocked all objects and tested the classes except a DAO which is using JDBCTemplate.
#RunWith(EasyMockRunner.class)
public class DummyDAOImplTest extends EasyMockSupport {
#TestSubject
private DummyDAOImpl dummyDAOImpl = new DummyDAOImpl ();
JdbcTemplate jdbcTemplateObject;
#Before
public void setUp(){
jdbcTemplateObject = EasyMock.createNiceMock(JdbcTemplate.class);
dummyDAOImpl.setJdbcTemplate(jdbcTemplateObject);
}
#Test
public void testGetApplicationConfigValueReturnNonNull(){
String query = "SELECT value FROM application_configuration WHERE tag=?";
String tag = "REFRESH_INTERVAL";
EasyMock.expect(jdbcTemplateObject.queryForObject(query,new Object[] {tag}, String.class)).andReturn("12");
EasyMock.replay(jdbcTemplateObject);
Assert.assertEquals(12,dummyDAOImpl.getApplicationConfigValue(tag));
}
}
public class ConfigurationDAOImpl implements ConfigurationDAO {
private JdbcTemplate jdbcTemplateObject;
#Override
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplateObject = jdbcTemplate;
}
#Override
public int getApplicationConfigValue(String tag) {
String query = "SELECT value FROM application_configuration WHERE tag=?";
String refreshTime = jdbcTemplateObject.queryForObject(query,new Object[] {tag}, String.class);
if(refreshTime != null && !"".equals(refreshTime))
return new Integer(refreshTime);
else
return 0;
}
}
Though in method testGetApplicationConfigValueReturnNonNull - I'm trying to mock it to return 12 but it always returns null.
It's the first time I'm using EasyMock. anything that I'm missing as already tried for and not able to crack it!
Best Regards,
Sundar
In fact, your only problem is your expectation line. It should be
EasyMock.expect(jdbcTemplateObject.queryForObject(eq(query), aryEq(new Object[] {tag}), eq(String.class))).andReturn("12");
By default, EasyMock will perform an equals on parameter to match the expectation. The things is that there are no equals defined for an array. So you need to specify a matcher for array (aryEq). And as soon as you have a matcher for an argument, you need to have one for all of them (for technical reasons).
The full code with some simplifications is below.
I assumed it is ConfigurationDAO that you want to test
You can replayAll since you are extending EasyMockSupport
You can use #Mock because of the runner
You do not need a nice mock. In fact, not using it here will have shown a nice exception about the unexpected call that would have been really helpful for you
The mock is now also injected by the EasyMockRunner
I prefer to add a verifyAll at the end of most of my tests. It makes sure that all expectations were used
Static imports because I think it's clearer to read
Code:
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
#RunWith(EasyMockRunner.class)
public class DummyDAOImplTest extends EasyMockSupport {
#TestSubject
private ConfigurationDAOImpl dao = new ConfigurationDAOImpl();
#Mock
JdbcTemplate jdbcTemplateObject;
#Test
public void testGetApplicationConfigValueReturnNonNull(){
String query = "SELECT value FROM application_configuration WHERE tag=?";
String tag = "REFRESH_INTERVAL";
expect(jdbcTemplateObject.queryForObject(eq(query), aryEq(new Object[] {tag}), eq(String.class))).andReturn("12");
replayAll();
assertEquals(12, dao.getApplicationConfigValue(tag));
verifyAll();
}
}
Probably you need to load the Spring context
#ContextConfiguration(locations = "classpath:application-context-test.xml")
#RunWith(EasyMockRunner.class) public class DummyDAOImplTest extends EasyMockSupport { ...
Override your appplication-context like this
application-context-test.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx/ http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"><import resource="application-context.xml"/><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:your-db-conection" />
<property name="username" value="" />
<property name="password" value="" />

Null pointer for field injection

I'm missing fundamental things here that I do, I'm sorry for this question, basically I tried to simulate my own question from Autowring for #Sevice field failed , but in very simple form , I tried to somehow raise errors on purpose for building understanding, but when it comes, I just can't handle it.
x-servlet.xml
<beans xmlns= ...... >
<context:component-scan base-package="com" />
<context:annotation-config />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
com.domain
Boss.java
package com.domain;
public class Boss {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Employee:
package com.domain;
import org.springframework.beans.factory.annotation.Autowired;
public class Employee {
#Autowired
private Boss boss;
String nameBoss;
public String getNameBoss() {
nameBoss = this.boss.getName();
return nameBoss;
}
}
com.controller
controller.java :
package com.controller
import com.domain.Boss;
import com.domain.Employee;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class controller {
#RequestMapping("/try")
public String show() {
Boss b = new Boss();
b.setName(" hans");
Employee e = new Employee();
String bossName = e.getNameBoss();
System.out.println(bossName );
return "";
}
}
I was thinking that,
String bossName = e.getNameBoss();
in controller won't be null because Boss is already initialized right before Employee construction, but I'm wrong ..
Are you sure you want to have dependency injection (DI) for domain objects? This is not a typicall usage... For a DI, container have to create instances - so do not use new operator...
You can replace new operator using ApplicationContext.getBean() (iff the bean is of type prototype), but as I said above - even if you know how to create such beans, how should Spring know, which instance of Boss you want to have in Employee?
First thing you need is application context in controller, which should work to add interface org.springframework.context.ApplicationContextAware or you can simply autowire it and then use it "standard" way (ac is ApplicationContext):
Boss b = ac.getBean(Boss.class);
Employee e = ac.getBean(Employee.class, b);
I have Boss and Employee marked with annotations as:
#Component
#Scope("prototype")
public class Boss {
...
}
#Component
#Scope("prototype")
public class Employee {
// #Autowire - wrong
Boss boss;
public Employee(Boss boss) {
this.boss = boss;
}
...
}

Resources