Is it really mandatory to give bean an id - spring

I thought naming a bean with id is not mandatory before i get stuck here.
dispatcher-servlet.xml
<mvc:annotation-driven />
<context:annotation-config />
<context:component-scan
base-package="com.springMVC.*"></context:component-scan>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/Views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename">
<value>/WEB-INF/messagekeys</value>
</property>
</bean>
messagekeys.properties
NotEmpty.user1.name = UserName cannot be empty
Size.user1.name = Name should have a length between 6 and 16
Pattern.user1.name = Name should not contain numeric value
Min.user1.age = Age cannot be less than 12
Max.user1.age = Age cannot be more than 60
NotNull.user1.age = Please enter your age
NotEmpty.user1.email = email cannot be left blank
Email.user1.email = email is not valid
NotEmpty.user1.country = Enter valid country
User.java
package com.springMVC.model;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#Scope("request")
public class User {
#NotEmpty
#Size(min=6,max=16)
#Pattern(regexp = "[^0-9]+")
private String name;
#Min(value=12)
#Max(value=60)
#NotNull
private Integer age;
#NotEmpty
#Email
private String email;
#NotEmpty
private String country;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setEmail(String email) {
this.email = email;
}
public void setCountry(String country) {
this.country = country;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public String getEmail() {
return email;
}
public String getCountry() {
return country;
}
}
When i use the bean InternalResourceViewResolver without bean id, it works fine.
But when i use the bean ReloadableResourceBundleMessageSource without bean id, it doesn't render error messages from messages.properties
When i give ReloadableResourceBundleMessageSource bean an id, it works perfect.
So, my question is Is naming a bean with an id mandatory?
Thanks in advance :)

Yes for message resource
When an ApplicationContext is loaded, it automatically searches for a MessageSource bean defined in the context. The bean must have the name messageSource. If such a bean is found, all calls to the preceding methods are delegated to the message source. If no message source is found, the ApplicationContext attempts to find a parent containing a bean with the same name. If it does, it uses that bean as the MessageSource. If the ApplicationContext cannot find any source for messages, an empty DelegatingMessageSource is instantiated in order to be able to accept calls to the methods defined above.
check here documentation

Related

Spring Boot -Hibernate 5 simple application initializing in 3 minutes

I am using Spring boot with Hibernate to connect with Oracle database. The application works fine but when I run the application with Dddl.auto flag set to update it takes 3 minutes just to initialize the entity manager. here are my model classes and cfg.xml.
Hibernate.cfg.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"classpath://org/hibernate/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#hhhh.cpckubosallr.ap-south-1.rds.amazonaws.com:1610:gghg</property>
<property name="hibernate.connection.username">DEMO</property>
<property name="hibernate.connection.password">ggggg#78GHTd</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</property>
<property name="show_sql">true</property>
<property name="hibernate.connection.pool_size">5</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hbm2ddl.auto">update</property>
<mapping class ="student.mappings.model.Student" />
<mapping class ="student.mappings.model.Vehicle" />
<mapping class ="student.mappings.model.Subject" />
</session-factory>
</hibernate-configuration>
Model classes:
#Entity
#Table(name="STUDENT", schema="JAVACODE")
public class Student
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Column(name="name")
private String name;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="vehicle_id")
private Vehicle vehicle;
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", vehicle=" + vehicle + ", subject=" + subject + "]";
}
public Vehicle getVehicle()
{
return vehicle;
}
public void setVehicle(Vehicle vehicle)
{
this.vehicle = vehicle;
}
#OneToMany(cascade=CascadeType.ALL)
#JoinColumn(name="subject_id")
private List<Subject> subject;
public List<Subject> getSubject()
{
return subject;
}
public void setSubject(List<Subject> subject)
{
this.subject = subject;
}
public Student(Long id, String name, Vehicle vehicle, List<Subject> subject)
{
super();
this.id = id;
this.name = name;
this.vehicle = vehicle;
this.subject = subject;
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Student()
{
super();
}
public Student(Long id, String name)
{
super();
this.id = id;
this.name = name;
}
public Student(Long id, String name, Vehicle vehicle) {
super();
this.id = id;
this.name = name;
this.vehicle = vehicle;
}
}
Application.java:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan("student.mappings")
#EntityScan("student.mappings")
#PropertySource(value= {"classpath:application.properties"})
public class StudentMappingsTemplateClient
{
public static void main(String[] args) {
SpringApplication.run(StudentMappingsTemplateClient.class, args);
}
}

Getting the error NoSuchMethodError: org.apache.cassandra.thrift.TBinaryProtocol when using Apache Cassandra,Kundera,Spring MVC

I keep getting the message
java.lang.NoSuchMethodError: org.apache.cassandra.thrift.TBinaryProtocol: method <init>(Lorg/apache/thrift/transport/TTransport;)V not found
at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.initiateClient(CassandraSchemaManager.java:446)
at com.impetus.kundera.configure.schema.api.AbstractSchemaManager.exportSchema(AbstractSchemaManager.java:101)
at com.impetus.client.cassandra.schemamanager.CassandraSchemaManager.exportSchema(CassandraSchemaManager.java:138)
at com.impetus.kundera.configure.SchemaConfiguration.configure(SchemaConfiguration.java:172)
at com.impetus.kundera.configure.ClientMetadataBuilder.buildClientFactoryMetadata(ClientMetadataBuilder.java:45)
at com.impetus.kundera.persistence.EntityManagerFactoryImpl.configureClientFactories(EntityManagerFactoryImpl.java:352)
at com.impetus.kundera.persistence.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:116)
at com.impetus.kundera.KunderaPersistence.createEntityManagerFactory(KunderaPersistence.java:83)
at com.impetus.kundera.KunderaPersistence.createContainerEntityManagerFactory(KunderaPersistence.java:65)
Whenever I try to run my Java Spring MVC 3.2 Project. I am trying to connect to Apache Cassandra 1.2.8 that I have installed on my machine from the Spring WebApp using Kundera. I have included the following dependencies in the pom.xml file of the project:
scale7-pelops(1.3-1.1.x)
cassandra-all & cassandra-clientutil (1.2.8)
kundera-core & kundera-cassandra (2.6)
My Spring Project uses XML-less configuration (Java Config) and JPA apart from kundera's persistence.xml which is under {PROJECT}/src/main/resources/META-INF so as to be at the base of the classpath during deployment. My persistence.xml looks like:
<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="cassandra_pu">
<provider>com.impetus.kundera.KunderaPersistence</provider>
<class>org.tutiworks.orm.Role</class>
<class>org.tutiworks.orm.User</class>
<properties>
<property name="kundera.nodes" value="localhost"/>
<property name="kundera.port" value="9160"/>
<property name="kundera.keyspace" value="afrikana"/>
<property name="kundera.dialect" value="cassandra"/>
<property name="kundera.ddl.auto.prepare" value="update"/>
<property name="kundera.client.lookup.class" value="com.impetus.client.cassandra.pelops.PelopsClientFactory" />
<property name="kundera.cache.provider.class" value="com.impetus.kundera.cache.ehcache.EhCacheProvider"/>
<property name="kundera.cache.config.resource" value="/ehcache-cassandra.xml"/>
</properties>
</persistence-unit>
</persistence>
And the configuration class creating the entityManager looks like:
#Configuration
public class SpringDataConfig extends WebMvcConfigurerAdapter{
#Autowired
private Environment env;
#Value("${kundera.nodes}") private String node;
#Value("${kundera.port}") private String port;
#Value("${kundera.keyspace}") private String keyspace;
#Value("${kundera.dialect}") private String dialect;
#Value("${kundera.ddl.auto.prepare}") private String dbGenerator;
#Value("${kundera.cache.provider.class}") private String cacheClass;
#Value("${kundera.client.lookup.class}") private String lookupClass;
#Value("${kundera.cache.config.resource}") private String configResource;
#Value("${persistence.unit.name}") private String persistenceUnitName;
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPersistenceUnitName(persistenceUnitName);
return em;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
The following class shows how the persistence context is used.
public abstract class GenericDAO< T extends Serializable > {
private Class<T> clazz;
#PersistenceContext
EntityManager entityManager;
protected void setClazz( Class<T> clazzToSet ){
this.clazz = clazzToSet;
}
public T findOne( String id ){
return this.entityManager.find( this.clazz, id );
}
#SuppressWarnings("unchecked")
public List< T > findAll(){
return this.entityManager.createQuery( "from " + this.clazz.getName() )
.getResultList();
}
public void save( T entity ){
this.entityManager.persist( entity );
}
public void update( T entity ){
this.entityManager.merge( entity );
}
public void delete( T entity ){
this.entityManager.remove( entity );
}
public void deleteById( String entityId ){
T entity = this.findOne( entityId );
this.delete( entity );
}
}
A sample of the ORM that is mapped to a column family in Apache Cassandra installation looks like the following.
#XmlRootElement(name = "Role")
#Entity(name="Role")
#Table(name = "roles", schema = "afrikana#cassandra_pu")
public class Role implements Serializable {
private static final long serialVersionUID = 9127322651789683331L;
#Id
#Column(name="id")
#XmlID
private String id;
#Column(name = "role_name")
#XmlElement(name = "role_name")
private String roleName;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Where would I be going wrong with my configuration? What I'm I missing? How do I fix the error?
Kundera cassandra libraries are running on 1.2.4 version. Ideally 1.2.8 or higher versions should always be backward compatible, but in this case unfortunately they are not!

Error in entity retrieval

I am attempting to handle an 'entity' through annotation instead of a hibernate xml mapping.
I face a situation where addition succeeds but retrieval fails - help is appreciated.
Model class:
#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;
#Column(name = "MONEY")
private Double money;
.....setters and getters
}
spring configuration:
<context:annotation-config />
<context:component-scan base-package="org.spring.entity,org.spring.service" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
....
</bean>
<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
...
<property name="packagesToScan">
<list>
<value>org.spring.entity</value>
<value>org.spring.service</value>
</list>
</property>
<property name="hibernateProperties">
...
</property>
</bean>
Service class:
public void add(String firstName, String lastName, Double money) {
// Retrieve session from Hibernate
Session session = sessionFactory.openSession();
try{
// Create a new person
Person person = new Person();
person.setFirstName(firstName);
person.setLastName(lastName);
person.setMoney(money);
// Save
session.save(person);
}
finally{
session.close();
}
}
public void edit(Integer id, String firstName, String lastName, Double money) {
// Retrieve session from Hibernate
Session session = sessionFactory.openSession();
try{
// Retrieve existing person via id
Query query = session.createQuery("FROM Person WHERE ID=?");<=FAILS HERE
query.setInteger(0, id);
Person person = (Person)query.list().get(0);
......
}
The error is as below:
Exception in thread "main" org.hibernate.hql.internal.ast.QuerySyntaxException:
person is not mapped [from person where ID=?]
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClass
Persister(SessionFactoryHelper.java:180)
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement
(FromElementFactory.java:110)
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromCla
use.java:93)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlW
alker.java:324)
Your HQL is wrong, Do this way:
(in case of multiple results, their might be some syntax left right, please check.)
Query query = session.createQuery("FROM Person WHERE ID=:ID")
List list=query.setParameter("ID",ID).list();
or
(in case of Single result)
Person person =new Person ();
person =(Person ) session.get(Person .class, ID);

Spring JPA Repository Autowire Issue

I followed a youtube video tutorial for setting up a Spring JPA project but im still having issues with my Spring JPA project and was hoping someone could help.
http://www.youtube.com/watch?v=kM7Gr3XTzIg
The main problem seems to be Autowiring my JPARepository. I have tested that my entityManager / persistence unit works via the following test code (it pulls back the expected record).
public class CheckEntityManagerWorksTest {
private static Logger logger = Logger.getLogger(CheckEntityManagerWorksTest.class.getName());
private static EntityManagerFactory emFactory;
private static EntityManager em;
#BeforeClass
public static void setUp() throws Exception {
try {
logger.info("Building JPA EntityManager for unit tests");
emFactory = Persistence.createEntityManagerFactory("pu");
em = emFactory.createEntityManager();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception during JPA EntityManager instanciation.");
}
}
#AfterClass
public static void tearDown() throws Exception {
logger.info("Shuting down Hibernate JPA layer.");
if (em != null) {
em.close();
}
if (emFactory != null) {
emFactory.close();
}
}
#Test
public void testPersistence() {
try {
em.getTransaction().begin();
Integer id = 51;
Accounts account = em.find(Accounts.class, id);
assertNotNull(account);
System.out.println("Account username: " + account.getUsername());
em.getTransaction().commit();
} catch (Exception ex) {
em.getTransaction().rollback();
ex.printStackTrace();
fail("Exception during testPersistence");
}
}
}
As i said that test works for connecting to the database, etc. but the test below fails with a autowire exception (stack trace at very bottom of page):
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("**/applicationContext.xml")
public class AccountsRepositoryTest {
#Autowired
AccountsRepository repo;
#Test
public void testAccountsRepository() {
assertNotNull(repo.findOne(51));
}
}
Below is my setup.
Persistence.xml
<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="pu">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/craigtest"/>
<property name="hibernate.connection.password" value="craigtest"/>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="hibernate.connection.username" value="craigtest"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="pu"/>
</bean>
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf"/>
</bean>
<jpa:repositories base-package="com.mycompany.jpaspring.repositories" />
</beans>
My Repository:
package com.mycompany.jpaspring.repositories;
import com.mycompany.jpaspring.entity.Accounts;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountsRepository extends JpaRepository<Accounts, Integer>{
}
My Entity:
package com.mycompany.jpaspring.entity;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "ACCOUNTS")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Accounts.findAll", query = "SELECT a FROM Accounts a"),
#NamedQuery(name = "Accounts.findById", query = "SELECT a FROM Accounts a WHERE a.id = :id"),
#NamedQuery(name = "Accounts.findByUsername", query = "SELECT a FROM Accounts a WHERE a.username = :username"),
#NamedQuery(name = "Accounts.findByFirstname", query = "SELECT a FROM Accounts a WHERE a.firstname = :firstname"),
#NamedQuery(name = "Accounts.findByLastname", query = "SELECT a FROM Accounts a WHERE a.lastname = :lastname")})
public class Accounts implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "ID")
private Integer id;
#Basic(optional = false)
#Column(name = "USERNAME")
private String username;
#Column(name = "FIRSTNAME")
private String firstname;
#Column(name = "LASTNAME")
private String lastname;
public Accounts() {
}
public Accounts(Integer id) {
this.id = id;
}
public Accounts(Integer id, String username) {
this.id = id;
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
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
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Accounts)) {
return false;
}
Accounts other = (Accounts) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.mycompany.jpaspring.entity.Accounts[ id=" + id + " ]";
}
}
Stack trace:
-------------------------------------------------------------------------------
Test set: com.mycompany.jpaspring.AccountsRepositoryTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.797 sec <<< FAILURE!
testAccountsRepository(com.mycompany.jpaspring.AccountsRepositoryTest) Time elapsed: 0.507 sec <<< ERROR!
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.mycompany.jpaspring.AccountsRepositoryTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.mycompany.jpaspring.repositories.AccountsRepository com.mycompany.jpaspring.AccountsRepositoryTest.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.jpaspring.repositories.AccountsRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
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:601)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.mycompany.jpaspring.repositories.AccountsRepository com.mycompany.jpaspring.AccountsRepositoryTest.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.jpaspring.repositories.AccountsRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:513)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 32 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.jpaspring.repositories.AccountsRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:947)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485)
... 34 more
Everything seems to be fine to me, except for this line:
#ContextConfiguration("**/applicationContext.xml")
Do you really need to import multiple xml files?
In which folder is the applicationContext.xml exactly?
Could you try replacing the above with a full path reference? Something like this:
#ContextConfiguration("classpath:/com/.../application-context.xml")

Spring JPA Hibernate Oracle #OneToOne with Shared Primary Key fails on insert - foreign key violation

I have 2 Entities that I am trying to set up using a #OneToOne relationship.
I am using Oracle 11g as the database and User Table has a generated ID via a sequence. This Id from the user table is the Primary Key and Foreign key in the UserProfile table.
So basically a User is mapped to 1 and only 1 User Profile and a User Profile maps back to only 1 User.
I have seeded data in my database and I can read User Object with a User Profile without problem. But when I try to insert a new User Object with a New UserProfile object in a transaction it fails with a Foreign Key Violation in my UserProfile table.
It seems to be a common problem out there with a #OneToOne with Shared primary key, but I can't see to find a answer that works. Can someone point me in the right direction?
I can see that the Id in USerProfile gets set correctly, just on the commit to the database it throws the violation. It almost seems like the UserProfile is being committed to the database before User. Is there a way to persist the User first without have to persist these objects separately?
Here are my entities:
package com.company.ca.domain;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="USERS")
#SequenceGenerator(name="USERS_SEQ", sequenceName="USERS_SEQ", allocationSize=1)
public class Users implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator="USERS_SEQ")
private Long id;
#Column(name="USERNAME", unique=true)
private String email;
private String password;
#Column(name="CREATED_DATE", insertable=false, updatable=false)
private Date createdDate;
#Column(name="CREATED_BY")
private String createdBy;
#Column(name="LAST_UPDATED_DATE")
private Date lastUpdatedDate;
#Column(name="LAST_UPDATED_BY")
private String lastUpdatedBy;
private int enabled;
#OneToOne(cascade = CascadeType.ALL, mappedBy="user")
#PrimaryKeyJoinColumn(name="ID", referencedColumnName="USER_ID")
private UsersProfile usersProfile;
public Users() {
}
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;
}
public int getEnabled() {
return enabled;
}
public void setEnabled(int enabled) {
this.enabled = enabled;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
public String getLastUpdatedBy() {
return lastUpdatedBy;
}
public void setLastUpdatedBy(String lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
public UsersProfile getUsersProfile() {
return usersProfile;
}
public void setUsersProfile(UsersProfile usersProfile) {
this.usersProfile = usersProfile;
}
}
package com.company.ca.domain;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
#Entity
#Table(name="USERS_PROFILE")
#org.hibernate.annotations.GenericGenerator(name="user-primarykey", strategy="foreign",
parameters={#org.hibernate.annotations.Parameter(name="property", value="user")
})
public class UsersProfile implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(generator = "user-primarykey")
#Column(name = "USER_ID")
private Long userId;
#OneToOne
#PrimaryKeyJoinColumn(name="USER_ID", referencedColumnName="ID")
private Users user;
#Column(name="FIRST_NAME")
private String firstName;
#Column(name="LAST_NAME")
private String lastName;
#Column(name="PHONE_NUMBER")
private String phoneNumber;
#Column(name="CREATED_DATE", insertable=false, updatable=false)
private Date createdDate;
#Column(name="CREATED_BY")
private String createdBy;
#Column(name="LAST_UPDATED_DATE")
private Date lastUpdatedDate;
#Column(name="LAST_UPDATED_BY")
private String lastUpdatedBy;
public UsersProfile() {
super();
}
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 getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Users getUser() {
return user;
}
public void setUser(Users user) {
this.user = user;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
public String getLastUpdatedBy() {
return lastUpdatedBy;
}
public void setLastUpdatedBy(String lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
}
Here is my DAO and JUnit:
package com.company.ca.persistence;
import org.springframework.data.repository.CrudRepository;
import com.company.ca.domain.Users;
public interface UserDAO extends CrudRepository<Users, Long> {
}
package com.company.ca.persistence.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import com.company.ca.domain.Users;
import com.company.ca.domain.UsersProfile;
import com.company.ca.persistence.UserDAO;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
(
locations = {
"classpath*:/spring-persistence.xml"
}
)
#TransactionConfiguration(defaultRollback=false)
#Service
public class UserDAOImplTest extends AbstractTransactionalJUnit4SpringContextTests {
protected final Log logger = LogFactory.getLog(getClass());
#Autowired
UserDAO userDAO;
#Test
public void testFindUser() {
Users testUser = userDAO.findOne(new Long(2));
Assert.assertNotNull("User Object should not be null", testUser);
Assert.assertNotNull("User Profile should not be null", testUser.getUsersProfile());
}
#Test
//#Transactional(propagation=Propagation.MANDATORY)
public void testCreateUser() {
String email = "test.user2#testCompany.com";
String firstName = "Test 2";
String lastName = "User";
String phoneNumber = "1234567890";
String createdBy = "IT_SYSTEM#system.com";
String password = "password";
// now lets create the user
Users user = new Users();
user.setCreatedBy(createdBy);
user.setPassword(password);
user.setEmail(email);
user.setEnabled(0);
UsersProfile userProfile = new UsersProfile();
userProfile.setCreatedBy(createdBy);
userProfile.setFirstName(firstName);
userProfile.setLastName(lastName);
userProfile.setPhoneNumber(phoneNumber);
userProfile.setUser(user);
user.setUsersProfile(userProfile);
userDAO.save(user);
Assert.assertNotNull("UserId was not returned...", user.getId());
Assert.assertEquals("Expected email not set correctly", email,
user.getEmail());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<context:annotation-config />
<context:property-placeholder location="classpath*:/persistence.properties" />
<jpa:repositories base-package="com.company.ca.persistence"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.company.ca.domain" />
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.max_fetch_depth">5</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
And here is my output:
10:28:13,400 DEBUG SQL:104 - select USERS_SEQ.nextval from dual
Hibernate: select USERS_SEQ.nextval from dual
10:28:13,500 DEBUG SQL:104 - insert into USERS (CREATED_BY, USERNAME, enabled, LAST_UPDATED_BY, LAST_UPDATED_DATE, password, id) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USERS (CREATED_BY, USERNAME, enabled, LAST_UPDATED_BY, LAST_UPDATED_DATE, password, id) values (?, ?, ?, ?, ?, ?, ?)
10:28:13,501 TRACE BasicBinder:83 - binding parameter [1] as [VARCHAR] - VRS_SYSTEM#audatex.com
10:28:13,501 TRACE BasicBinder:83 - binding parameter [2] as [VARCHAR] - colin.moore3#audatex.com
10:28:13,502 TRACE BasicBinder:83 - binding parameter [3] as [INTEGER] - 0
10:28:13,502 TRACE BasicBinder:71 - binding parameter [4] as [VARCHAR] - <null>
10:28:13,504 TRACE BasicBinder:71 - binding parameter [5] as [TIMESTAMP] - <null>
10:28:13,505 TRACE BasicBinder:83 - binding parameter [6] as [VARCHAR] - test
10:28:13,505 TRACE BasicBinder:83 - binding parameter [7] as [BIGINT] - 117
10:28:13,577 DEBUG SQL:104 - insert into USERS_PROFILE (CREATED_BY, FIRST_NAME, LAST_NAME, LAST_UPDATED_BY, LAST_UPDATED_DATE, PHONE_NUMBER, USER_ID) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USERS_PROFILE (CREATED_BY, FIRST_NAME, LAST_NAME, LAST_UPDATED_BY, LAST_UPDATED_DATE, PHONE_NUMBER, USER_ID) values (?, ?, ?, ?, ?, ?, ?)
10:28:13,579 TRACE BasicBinder:83 - binding parameter [1] as [VARCHAR] - VRS_SYSTEM#audatex.com
10:28:13,579 TRACE BasicBinder:83 - binding parameter [2] as [VARCHAR] - Colin
10:28:13,579 TRACE BasicBinder:83 - binding parameter [3] as [VARCHAR] - Moore
10:28:13,580 TRACE BasicBinder:71 - binding parameter [4] as [VARCHAR] - <null>
10:28:13,580 TRACE BasicBinder:71 - binding parameter [5] as [TIMESTAMP] - <null>
10:28:13,580 TRACE BasicBinder:83 - binding parameter [6] as [VARCHAR] - 4164983787
10:28:13,581 TRACE BasicBinder:83 - binding parameter [7] as [BIGINT] - 117
10:28:13,715 WARN SqlExceptionHelper:143 - SQL Error: 2291, SQLState: 23000
10:28:13,716 ERROR SqlExceptionHelper:144 - ORA-02291: integrity constraint (SYSTEM.FK_USER_ID) violated - parent key not found
10:28:13,716 WARN SqlExceptionHelper:143 - SQL Error: 2291, SQLState: 23000
10:28:13,716 ERROR SqlExceptionHelper:144 - ORA-02291: integrity constraint (SYSTEM.FK_USER_ID) violated - parent key not found
10:28:13,719 ERROR BatchingBatch:119 - HHH000315: Exception executing batch [ORA-02291: integrity constraint (SYSTEM.FK_USER_ID) violated - parent key not found
Your mapping is wrong. In a bidirectional asociation, one side is the owner of the association, and tells how the association is mapped. The other side is the inverse side, and just says "look at the other side for the mapping" using the mappedBy attribute.
See the documentation for an exemple:
#Entity
class UserProfile {
#Id Integer id;
#MapsId #OneToOne
#JoinColumn(name = "user_id")
User user;
}
#Entity
class Person {
#Id #GeneratedValue
Integer id;
#OneToOne(mappedBy = "user")
private UserProfile profile;
}

Resources