diff --git a/starting/spring-jpa/.classpath b/starting/spring-jpa/.classpath
new file mode 100644
index 0000000000..ca257cf1f9
--- /dev/null
+++ b/starting/spring-jpa/.classpath
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/starting/spring-jpa/.gitignore b/starting/spring-jpa/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/starting/spring-jpa/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/starting/spring-jpa/.project b/starting/spring-jpa/.project
new file mode 100644
index 0000000000..235ae29ecf
--- /dev/null
+++ b/starting/spring-jpa/.project
@@ -0,0 +1,43 @@
+
+
+ spring-jpa
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.springframework.ide.eclipse.core.springbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.springframework.ide.eclipse.core.springnature
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.jsdt.core.jsNature
+
+
diff --git a/starting/spring-jpa/.settings/.jsdtscope b/starting/spring-jpa/.settings/.jsdtscope
new file mode 100644
index 0000000000..b46b9207a8
--- /dev/null
+++ b/starting/spring-jpa/.settings/.jsdtscope
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/starting/spring-jpa/.settings/org.eclipse.jdt.core.prefs b/starting/spring-jpa/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..c201ee1f7a
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,95 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/starting/spring-jpa/.settings/org.eclipse.jdt.ui.prefs b/starting/spring-jpa/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000000..471e9b0d81
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+#Sat Jan 21 23:04:06 EET 2012
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=true
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=true
+sp_cleanup.make_private_fields_final=false
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=false
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=true
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=true
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/starting/spring-jpa/.settings/org.eclipse.m2e.core.prefs b/starting/spring-jpa/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000..f897a7f1cb
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/starting/spring-jpa/.settings/org.eclipse.m2e.wtp.prefs b/starting/spring-jpa/.settings/org.eclipse.m2e.wtp.prefs
new file mode 100644
index 0000000000..ef86089622
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.m2e.wtp.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false
diff --git a/starting/spring-jpa/.settings/org.eclipse.wst.common.component b/starting/spring-jpa/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000000..0327e45de6
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/starting/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml b/starting/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000000..a67649dfa5
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/starting/spring-jpa/.settings/org.eclipse.wst.jsdt.ui.superType.container b/starting/spring-jpa/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000000..3bd5d0a480
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/starting/spring-jpa/.settings/org.eclipse.wst.jsdt.ui.superType.name b/starting/spring-jpa/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000000..05bd71b6ec
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/starting/spring-jpa/.settings/org.eclipse.wst.validation.prefs b/starting/spring-jpa/.settings/org.eclipse.wst.validation.prefs
new file mode 100644
index 0000000000..0d0aee4f72
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.wst.validation.prefs
@@ -0,0 +1,15 @@
+DELEGATES_PREFERENCE=delegateValidatorList
+USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
+USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
+USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.402.v201212031633
+disabled=06target
+eclipse.preferences.version=1
+override=true
+suspend=false
+vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01
+vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01
+vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01
+vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01
+vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01
+vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02
+vf.version=3
diff --git a/starting/spring-jpa/.settings/org.eclipse.wst.ws.service.policy.prefs b/starting/spring-jpa/.settings/org.eclipse.wst.ws.service.policy.prefs
new file mode 100644
index 0000000000..9cfcabe16f
--- /dev/null
+++ b/starting/spring-jpa/.settings/org.eclipse.wst.ws.service.policy.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.wst.ws.service.policy.projectEnabled=false
diff --git a/starting/spring-jpa/.springBeans b/starting/spring-jpa/.springBeans
new file mode 100644
index 0000000000..7623a7e888
--- /dev/null
+++ b/starting/spring-jpa/.springBeans
@@ -0,0 +1,14 @@
+
+
+ 1
+
+
+
+
+
+
+ src/main/webapp/WEB-INF/mvc-servlet.xml
+
+
+
+
diff --git a/starting/spring-jpa/README.md b/starting/spring-jpa/README.md
new file mode 100644
index 0000000000..c62c4eabed
--- /dev/null
+++ b/starting/spring-jpa/README.md
@@ -0,0 +1,8 @@
+=========
+
+## Spring JPA Example Project
+
+
+### Relevant Articles:
+- [Spring 3 and JPA with Hibernate](http://www.baeldung.com/2011/12/13/the-persistence-layer-with-spring-3-1-and-jpa/)
+- [Transactions with Spring 3 and JPA](http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/)
diff --git a/starting/spring-jpa/pom.xml b/starting/spring-jpa/pom.xml
new file mode 100644
index 0000000000..849a62ee36
--- /dev/null
+++ b/starting/spring-jpa/pom.xml
@@ -0,0 +1,218 @@
+
+ 4.0.0
+
+ org.baeldung
+ spring-jpa
+ 0.1-SNAPSHOT
+
+ war
+ spring-jpa
+
+
+
+
+
+
+ org.springframework
+ spring-web
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-orm
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-context
+ ${org.springframework.version}
+
+
+
+
+
+ org.hibernate
+ hibernate-entitymanager
+ ${hibernate.version}
+
+
+ org.javassist
+ javassist
+ 3.18.1-GA
+
+
+ mysql
+ mysql-connector-java
+ ${mysql-connector-java.version}
+ runtime
+
+
+
+
+
+ org.hibernate
+ hibernate-validator
+ ${hibernate-validator.version}
+
+
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+ test
+
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+ test
+
+
+
+ junit
+ junit-dep
+ ${junit.version}
+ test
+
+
+
+ org.hamcrest
+ hamcrest-core
+ ${org.hamcrest.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-library
+ ${org.hamcrest.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+
+
+ spring-jpa
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.7
+ 1.7
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+ ${cargo-maven2-plugin.version}
+
+ true
+
+ jetty8x
+ embedded
+
+
+
+
+
+
+ 8082
+
+
+
+
+
+
+
+
+
+
+
+ 4.0.0.RELEASE
+ 3.2.0.RELEASE
+
+
+ 4.3.0.Final
+ 5.1.28
+
+
+ 1.7.5
+ 1.0.11
+
+
+ 5.0.2.Final
+
+
+ 16.0-rc1
+ 3.2.1
+
+
+ 1.3
+ 4.11
+ 1.9.5
+
+ 4.3
+ 4.3.1
+
+ 2.1.0
+
+
+
+ 3.1
+ 2.4
+ 2.16
+ 2.6
+ 1.4.5
+
+
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java b/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java
new file mode 100644
index 0000000000..13007d9fcc
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java
@@ -0,0 +1,46 @@
+package org.baeldung.persistence.dao;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+public abstract class AbstractJpaDAO {
+
+ private Class clazz;
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ public final void setClazz(final Class clazzToSet) {
+ this.clazz = clazzToSet;
+ }
+
+ public T findOne(final long id) {
+ return entityManager.find(clazz, id);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List findAll() {
+ return entityManager.createQuery("from " + clazz.getName()).getResultList();
+ }
+
+ public void create(final T entity) {
+ entityManager.persist(entity);
+ }
+
+ public T update(final T entity) {
+ return entityManager.merge(entity);
+ }
+
+ public void delete(final T entity) {
+ entityManager.remove(entity);
+ }
+
+ public void deleteById(final long entityId) {
+ final T entity = findOne(entityId);
+ delete(entity);
+ }
+
+}
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java b/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java
new file mode 100644
index 0000000000..77978c5cf2
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java
@@ -0,0 +1,17 @@
+package org.baeldung.persistence.dao;
+
+import org.baeldung.persistence.model.Foo;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class FooDao extends AbstractJpaDAO implements IFooDao {
+
+ public FooDao() {
+ super();
+
+ setClazz(Foo.class);
+ }
+
+ // API
+
+}
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java b/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java
new file mode 100644
index 0000000000..f5799522e2
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java
@@ -0,0 +1,21 @@
+package org.baeldung.persistence.dao;
+
+import java.util.List;
+
+import org.baeldung.persistence.model.Foo;
+
+public interface IFooDao {
+
+ Foo findOne(long id);
+
+ List findAll();
+
+ void create(Foo entity);
+
+ Foo update(Foo entity);
+
+ void delete(Foo entity);
+
+ void deleteById(long entityId);
+
+}
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java b/starting/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java
new file mode 100644
index 0000000000..8e1dee33e8
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java
@@ -0,0 +1,83 @@
+package org.baeldung.persistence.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Foo implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long id;
+
+ @Column(nullable = false)
+ private String name;
+
+ public Foo() {
+ super();
+ }
+
+ public Foo(final String name) {
+ super();
+
+ this.name = name;
+ }
+
+ // API
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ //
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Foo other = (Foo) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Foo [name=").append(name).append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java b/starting/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java
new file mode 100644
index 0000000000..b07698c438
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java
@@ -0,0 +1,26 @@
+package org.baeldung.persistence.service;
+
+import org.baeldung.persistence.dao.IFooDao;
+import org.baeldung.persistence.model.Foo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional
+public class FooService {
+
+ @Autowired
+ private IFooDao dao;
+
+ public FooService() {
+ super();
+ }
+
+ // API
+
+ public void create(final Foo entity) {
+ dao.create(entity);
+ }
+
+}
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/spring/PersistenceJPAConfig.java b/starting/spring-jpa/src/main/java/org/baeldung/spring/PersistenceJPAConfig.java
new file mode 100644
index 0000000000..3b36b47438
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/spring/PersistenceJPAConfig.java
@@ -0,0 +1,85 @@
+package org.baeldung.spring;
+
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.google.common.base.Preconditions;
+
+// @Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-mysql.properties" })
+@ComponentScan({ "org.baeldung.persistence" })
+public class PersistenceJPAConfig {
+
+ @Autowired
+ private Environment env;
+
+ public PersistenceJPAConfig() {
+ super();
+ }
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(dataSource());
+ em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
+
+ final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ // vendorAdapter.set
+ em.setJpaVendorAdapter(vendorAdapter);
+ em.setJpaProperties(additionalProperties());
+
+ return em;
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ final DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(emf);
+ return transactionManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ final Properties additionalProperties() {
+ return new Properties() {
+ {
+ setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+
+ // setProperty("hibernate.globally_quoted_identifiers", "true");
+ // note: necessary in launchpad-storage, but causing problems here
+ }
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/java/org/baeldung/spring/PersistenceJPAConfigXml.java b/starting/spring-jpa/src/main/java/org/baeldung/spring/PersistenceJPAConfigXml.java
new file mode 100644
index 0000000000..98f4f47249
--- /dev/null
+++ b/starting/spring-jpa/src/main/java/org/baeldung/spring/PersistenceJPAConfigXml.java
@@ -0,0 +1,18 @@
+package org.baeldung.spring;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement
+@ComponentScan({ "org.baeldung.persistence" })
+@ImportResource({ "classpath:jpaConfig.xml" })
+public class PersistenceJPAConfigXml {
+
+ public PersistenceJPAConfigXml() {
+ super();
+ }
+
+}
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/resources/jpaConfig.xml b/starting/spring-jpa/src/main/resources/jpaConfig.xml
new file mode 100644
index 0000000000..a291786a5c
--- /dev/null
+++ b/starting/spring-jpa/src/main/resources/jpaConfig.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${hibernate.hbm2ddl.auto}
+ ${hibernate.dialect}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/resources/logback.xml b/starting/spring-jpa/src/main/resources/logback.xml
new file mode 100644
index 0000000000..1146dade63
--- /dev/null
+++ b/starting/spring-jpa/src/main/resources/logback.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/resources/persistence-mysql.properties b/starting/spring-jpa/src/main/resources/persistence-mysql.properties
new file mode 100644
index 0000000000..c4de4ceb80
--- /dev/null
+++ b/starting/spring-jpa/src/main/resources/persistence-mysql.properties
@@ -0,0 +1,10 @@
+# jdbc.X
+jdbc.driverClassName=com.mysql.jdbc.Driver
+jdbc.url=jdbc:mysql://localhost:3306/spring_jpa_01?createDatabaseIfNotExist=true
+jdbc.user=tutorialuser
+jdbc.pass=tutorialmy5ql
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create-drop
diff --git a/starting/spring-jpa/src/main/resources/webSecurityConfig.xml b/starting/spring-jpa/src/main/resources/webSecurityConfig.xml
new file mode 100644
index 0000000000..35dcb9c1ef
--- /dev/null
+++ b/starting/spring-jpa/src/main/resources/webSecurityConfig.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/webapp/WEB-INF/mvc-servlet.xml b/starting/spring-jpa/src/main/webapp/WEB-INF/mvc-servlet.xml
new file mode 100644
index 0000000000..a675fc6d95
--- /dev/null
+++ b/starting/spring-jpa/src/main/webapp/WEB-INF/mvc-servlet.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/webapp/WEB-INF/view/sample.jsp b/starting/spring-jpa/src/main/webapp/WEB-INF/view/sample.jsp
new file mode 100644
index 0000000000..7cc14b5dcd
--- /dev/null
+++ b/starting/spring-jpa/src/main/webapp/WEB-INF/view/sample.jsp
@@ -0,0 +1,7 @@
+
+
+
+
+ This is the body of the sample view
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/main/webapp/WEB-INF/web.xml b/starting/spring-jpa/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..90f2abc2f6
--- /dev/null
+++ b/starting/spring-jpa/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+
+
+
+ Spring JPA Application
+
+
+ contextClass
+
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+
+
+
+ contextConfigLocation
+ org.baeldung.spring
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
\ No newline at end of file
diff --git a/starting/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/starting/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java
new file mode 100644
index 0000000000..2d8de007db
--- /dev/null
+++ b/starting/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java
@@ -0,0 +1,58 @@
+package org.baeldung.persistence.service;
+
+import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
+
+import org.baeldung.persistence.model.Foo;
+import org.baeldung.spring.PersistenceJPAConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { PersistenceJPAConfig.class }, loader = AnnotationConfigContextLoader.class)
+public class FooServicePersistenceIntegrationTest {
+
+ @Autowired
+ private FooService service;
+
+ // tests
+
+ @Test
+ public final void whenContextIsBootstrapped_thenNoExceptions() {
+ //
+ }
+
+ @Test
+ public final void whenEntityIsCreated_thenNoExceptions() {
+ service.create(new Foo(randomAlphabetic(6)));
+ }
+
+ @Test(expected = DataIntegrityViolationException.class)
+ public final void whenInvalidEntityIsCreated_thenDataException() {
+ service.create(new Foo());
+ }
+
+ @Test(expected = DataIntegrityViolationException.class)
+ public final void whenEntityWithLongNameIsCreated_thenDataException() {
+ service.create(new Foo(randomAlphabetic(2048)));
+ }
+
+ @Test(expected = InvalidDataAccessApiUsageException.class)
+ public final void whenSameEntityIsCreatedTwice_thenDataException() {
+ final Foo entity = new Foo(randomAlphabetic(8));
+ service.create(entity);
+ service.create(entity);
+ }
+
+ @Test(expected = DataAccessException.class)
+ public final void temp_whenInvalidEntityIsCreated_thenDataException() {
+ service.create(new Foo());
+ }
+
+}
diff --git a/starting/spring-jpa/src/test/resources/.gitignore b/starting/spring-jpa/src/test/resources/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/starting/spring-jpa/src/test/resources/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file