This commit is contained in:
Jonathan Cook
2019-10-23 15:01:44 +02:00
parent db85c8f275
commit 684ec0d2e3
20486 changed files with 1642483 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
## JPA in Java
This module contains articles about the Java Persistence API (JPA) in Java.
### Relevant Articles
- [A Guide to SqlResultSetMapping](https://www.baeldung.com/jpa-sql-resultset-mapping)
- [A Guide to Stored Procedures with JPA](https://www.baeldung.com/jpa-stored-procedures)
- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast)
- [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph)
- [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time)
- [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date)
- [Composite Primary Keys in JPA](https://www.baeldung.com/jpa-composite-primary-keys)
- [Defining JPA Entities](https://www.baeldung.com/jpa-entities)
- [JPA @Basic Annotation](https://www.baeldung.com/jpa-basic-annotation)
- [Persisting Enums in JPA](https://www.baeldung.com/jpa-persisting-enums-in-jpa)
- More articles: [[next -->]](/java-jpa-2)
+117
View File
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>java-jpa</artifactId>
<name>java-jpa</name>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!--Compile time JPA API-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>${javax.persistence-api.version}</version>
</dependency>
<!--Runtime JPA implementation-->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>${maven-processor-plugin.version}</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>target/metamodel</outputDirectory>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper-maven-plugin.version}</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/metamodel</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<hibernate.version>5.4.0.Final</hibernate.version>
<eclipselink.version>2.7.4-RC1</eclipselink.version>
<postgres.version>42.2.5</postgres.version>
<javax.persistence-api.version>2.2</javax.persistence-api.version>
<maven-processor-plugin.version>3.3.3</maven-processor-plugin.version>
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
</properties>
</project>
@@ -0,0 +1,33 @@
package com.baeldung.jpa.basicannotation;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
@Entity
public class Course {
@Id
private int id;
@Basic(optional = false, fetch = FetchType.LAZY)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,25 @@
package com.baeldung.jpa.convertdates;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.sql.Date;
import java.time.LocalDate;
import java.util.Optional;
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate localDate) {
return Optional.ofNullable(localDate)
.map(Date::valueOf)
.orElse(null);
}
@Override
public LocalDate convertToEntityAttribute(Date date) {
return Optional.ofNullable(date)
.map(Date::toLocalDate)
.orElse(null);
}
}
@@ -0,0 +1,68 @@
package com.baeldung.jpa.datetime;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.*;
import java.util.Calendar;
public class DateTimeEntityRepository {
private EntityManagerFactory emf = null;
public DateTimeEntityRepository() {
emf = Persistence.createEntityManagerFactory("java8-datetime-postgresql");
}
public JPA22DateTimeEntity find(Long id) {
EntityManager entityManager = emf.createEntityManager();
JPA22DateTimeEntity dateTimeTypes = entityManager.find(JPA22DateTimeEntity.class, id);
entityManager.close();
return dateTimeTypes;
}
public void save(Long id) {
JPA22DateTimeEntity dateTimeTypes = new JPA22DateTimeEntity();
dateTimeTypes.setId(id);
//java.sql types: date/time
dateTimeTypes.setSqlTime(Time.valueOf(LocalTime.now()));
dateTimeTypes.setSqlDate(Date.valueOf(LocalDate.now()));
dateTimeTypes.setSqlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
//java.util types: date/calendar
java.util.Date date = new java.util.Date();
dateTimeTypes.setUtilTime(date);
dateTimeTypes.setUtilDate(date);
dateTimeTypes.setUtilTimestamp(date);
//Calendar
Calendar calendar = Calendar.getInstance();
dateTimeTypes.setCalendarTime(calendar);
dateTimeTypes.setCalendarDate(calendar);
dateTimeTypes.setCalendarTimestamp(calendar);
//java.time types
dateTimeTypes.setLocalTime(LocalTime.now());
dateTimeTypes.setLocalDate(LocalDate.now());
dateTimeTypes.setLocalDateTime(LocalDateTime.now());
//java.time types with offset
dateTimeTypes.setOffsetTime(OffsetTime.now());
dateTimeTypes.setOffsetDateTime(OffsetDateTime.now());
EntityManager entityManager = emf.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(dateTimeTypes);
entityManager.getTransaction().commit();
entityManager.close();
}
public void clean() {
emf.close();
}
}
@@ -0,0 +1,176 @@
package com.baeldung.jpa.datetime;
import javax.persistence.*;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.*;
import java.util.Calendar;
@Entity
public class JPA22DateTimeEntity {
@Id
private Long id;
//java.sql types
private Time sqlTime;
private Date sqlDate;
private Timestamp sqlTimestamp;
//java.util types
@Temporal(TemporalType.TIME)
private java.util.Date utilTime;
@Temporal(TemporalType.DATE)
private java.util.Date utilDate;
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date utilTimestamp;
//Calendar
@Temporal(TemporalType.TIME)
private Calendar calendarTime;
@Temporal(TemporalType.DATE)
private Calendar calendarDate;
@Temporal(TemporalType.TIMESTAMP)
private Calendar calendarTimestamp;
// java.time types
@Column(name = "local_time", columnDefinition = "TIME")
private LocalTime localTime;
@Column(name = "local_date", columnDefinition = "DATE")
private LocalDate localDate;
@Column(name = "local_date_time", columnDefinition = "TIMESTAMP")
private LocalDateTime localDateTime;
@Column(name = "offset_time", columnDefinition = "TIME WITH TIME ZONE")
private OffsetTime offsetTime;
@Column(name = "offset_date_time", columnDefinition = "TIMESTAMP WITH TIME ZONE")
private OffsetDateTime offsetDateTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Time getSqlTime() {
return sqlTime;
}
public void setSqlTime(Time sqlTime) {
this.sqlTime = sqlTime;
}
public Date getSqlDate() {
return sqlDate;
}
public void setSqlDate(Date sqlDate) {
this.sqlDate = sqlDate;
}
public Timestamp getSqlTimestamp() {
return sqlTimestamp;
}
public void setSqlTimestamp(Timestamp sqlTimestamp) {
this.sqlTimestamp = sqlTimestamp;
}
public java.util.Date getUtilTime() {
return utilTime;
}
public void setUtilTime(java.util.Date utilTime) {
this.utilTime = utilTime;
}
public java.util.Date getUtilDate() {
return utilDate;
}
public void setUtilDate(java.util.Date utilDate) {
this.utilDate = utilDate;
}
public java.util.Date getUtilTimestamp() {
return utilTimestamp;
}
public void setUtilTimestamp(java.util.Date utilTimestamp) {
this.utilTimestamp = utilTimestamp;
}
public Calendar getCalendarTime() {
return calendarTime;
}
public void setCalendarTime(Calendar calendarTime) {
this.calendarTime = calendarTime;
}
public Calendar getCalendarDate() {
return calendarDate;
}
public void setCalendarDate(Calendar calendarDate) {
this.calendarDate = calendarDate;
}
public Calendar getCalendarTimestamp() {
return calendarTimestamp;
}
public void setCalendarTimestamp(Calendar calendarTimestamp) {
this.calendarTimestamp = calendarTimestamp;
}
public LocalTime getLocalTime() {
return localTime;
}
public void setLocalTime(LocalTime localTime) {
this.localTime = localTime;
}
public LocalDate getLocalDate() {
return localDate;
}
public void setLocalDate(LocalDate localDate) {
this.localDate = localDate;
}
public LocalDateTime getLocalDateTime() {
return localDateTime;
}
public void setLocalDateTime(LocalDateTime localDateTime) {
this.localDateTime = localDateTime;
}
public OffsetTime getOffsetTime() {
return offsetTime;
}
public void setOffsetTime(OffsetTime offsetTime) {
this.offsetTime = offsetTime;
}
public OffsetDateTime getOffsetDateTime() {
return offsetDateTime;
}
public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
this.offsetDateTime = offsetDateTime;
}
}
@@ -0,0 +1,18 @@
package com.baeldung.jpa.datetime;
public class MainApp {
public static void main(String... args) {
DateTimeEntityRepository dateTimeEntityRepository = new DateTimeEntityRepository();
//Persist
dateTimeEntityRepository.save(100L);
//Find
JPA22DateTimeEntity dateTimeEntity = dateTimeEntityRepository.find(100L);
dateTimeEntityRepository.clean();
}
}
@@ -0,0 +1,6 @@
package com.baeldung.jpa.entity;
public enum Gender {
MALE,
FEMALE
}
@@ -0,0 +1,73 @@
package com.baeldung.jpa.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "STUDENT_NAME", length = 50, nullable = false, unique = false)
private String name;
@Transient
private Integer age;
@Temporal(TemporalType.DATE)
private Date birthDate;
@Enumerated(EnumType.STRING)
private Gender gender;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
}
@@ -0,0 +1,26 @@
package com.baeldung.jpa.entitygraph;
import com.baeldung.jpa.entitygraph.model.Post;
import com.baeldung.jpa.entitygraph.repo.PostRepository;
public class MainApp {
public static void main(String... args) {
Long postId = 1L;
Post post = null;
PostRepository postRepository = new PostRepository();
//Using EntityManager.find().
post = postRepository.find(postId);
post = postRepository.findWithEntityGraph(postId);
post = postRepository.findWithEntityGraph2(postId);
//Using JPQL: Query and TypedQuery
post = postRepository.findUsingJpql(postId);
//Using Criteria API
post = postRepository.findUsingCriteria(postId);
postRepository.clean();
}
}
@@ -0,0 +1,63 @@
package com.baeldung.jpa.entitygraph.model;
import javax.persistence.*;
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String reply;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private User user;
//...
public Comment() {
}
public Comment(String reply, Post post, User user) {
this.reply = reply;
this.post = post;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getReply() {
return reply;
}
public void setReply(String reply) {
this.reply = reply;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
@@ -0,0 +1,86 @@
package com.baeldung.jpa.entitygraph.model;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@NamedEntityGraph(
name = "post-entity-graph",
attributeNodes = {
@NamedAttributeNode("subject"),
@NamedAttributeNode("user"),
@NamedAttributeNode("comments"),
}
)
@NamedEntityGraph(
name = "post-entity-graph-with-comment-users",
attributeNodes = {
@NamedAttributeNode("subject"),
@NamedAttributeNode("user"),
@NamedAttributeNode(value = "comments", subgraph = "comments-subgraph"),
},
subgraphs = {
@NamedSubgraph(
name = "comments-subgraph",
attributeNodes = {
@NamedAttributeNode("user")
}
)
}
)
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String subject;
@OneToMany(mappedBy = "post")
private List<Comment> comments = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private User user;
//...
public Post() {
}
public Post(String subject, User user) {
this.subject = subject;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
@@ -0,0 +1,48 @@
package com.baeldung.jpa.entitygraph.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
//...
public User() {
}
public User(String email) {
this.email = email;
}
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
@@ -0,0 +1,93 @@
package com.baeldung.jpa.entitygraph.repo;
import com.baeldung.jpa.entitygraph.model.Post;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.HashMap;
import java.util.Map;
public class PostRepository {
private EntityManagerFactory emf = null;
public PostRepository() {
Map properties = new HashMap();
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
emf = Persistence.createEntityManagerFactory("entity-graph-pu", properties);
}
public Post find(Long id) {
EntityManager entityManager = emf.createEntityManager();
Post post = entityManager.find(Post.class, id);
entityManager.close();
return post;
}
public Post findWithEntityGraph(Long id) {
EntityManager entityManager = emf.createEntityManager();
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);
entityManager.close();
return post;
}
public Post findWithEntityGraph2(Long id) {
EntityManager entityManager = emf.createEntityManager();
EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
entityGraph.addAttributeNodes("subject");
entityGraph.addAttributeNodes("user");
entityGraph.addSubgraph("comments")
.addAttributeNodes("user");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);
entityManager.close();
return post;
}
public Post findUsingJpql(Long id) {
EntityManager entityManager = emf.createEntityManager();
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users");
Post post = entityManager.createQuery("Select p from Post p where p.id=:id", Post.class)
.setParameter("id", id)
.setHint("javax.persistence.fetchgraph", entityGraph)
.getSingleResult();
entityManager.close();
return post;
}
public Post findUsingCriteria(Long id) {
EntityManager entityManager = emf.createEntityManager();
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph-with-comment-users");
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Post> criteriaQuery = criteriaBuilder.createQuery(Post.class);
Root<Post> root = criteriaQuery.from(Post.class);
criteriaQuery.where(criteriaBuilder.equal(root.<Long>get("id"), id));
TypedQuery<Post> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setHint("javax.persistence.loadgraph", entityGraph);
Post post = typedQuery.getSingleResult();
entityManager.close();
return post;
}
public void clean() {
emf.close();
}
}
@@ -0,0 +1,91 @@
package com.baeldung.jpa.enums;
import javax.persistence.*;
@Entity
public class Article {
@Id
private int id;
private String title;
@Enumerated(EnumType.ORDINAL)
private Status status;
@Enumerated(EnumType.STRING)
private Type type;
@Basic
private int priorityValue;
@Transient
private Priority priority;
private Category category;
public Article() {
}
@PostLoad
void fillTransient() {
if (priorityValue > 0) {
this.priority = Priority.of(priorityValue);
}
}
@PrePersist
void fillPersistent() {
if (priority != null) {
this.priorityValue = priority.getPriority();
}
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public Priority getPriority() {
return priority;
}
public void setPriority(Priority priority) {
this.priority = priority;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
@@ -0,0 +1,17 @@
package com.baeldung.jpa.enums;
import java.util.stream.Stream;
public enum Category {
SPORT("S"), MUSIC("M"), TECHNOLOGY("T");
private String code;
Category(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
@@ -0,0 +1,28 @@
package com.baeldung.jpa.enums;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.stream.Stream;
@Converter(autoApply = true)
public class CategoryConverter implements AttributeConverter<Category, String> {
@Override
public String convertToDatabaseColumn(Category category) {
if (category == null) {
return null;
}
return category.getCode();
}
@Override
public Category convertToEntityAttribute(final String code) {
if (code == null) {
return null;
}
return Stream.of(Category.values())
.filter(c -> c.getCode().equals(code))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}
@@ -0,0 +1,24 @@
package com.baeldung.jpa.enums;
import java.util.stream.Stream;
public enum Priority {
LOW(100), MEDIUM(200), HIGH(300);
private int priority;
private Priority(int priority) {
this.priority = priority;
}
public int getPriority() {
return priority;
}
public static Priority of(int priority) {
return Stream.of(Priority.values())
.filter(p -> p.getPriority() == priority)
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}
@@ -0,0 +1,5 @@
package com.baeldung.jpa.enums;
public enum Status {
OPEN, REVIEW, APPROVED, REJECTED;
}
@@ -0,0 +1,5 @@
package com.baeldung.jpa.enums;
enum Type {
INTERNAL, EXTERNAL;
}
@@ -0,0 +1,60 @@
package com.baeldung.jpa.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedStoredProcedureQueries;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.ParameterMode;
import javax.persistence.StoredProcedureParameter;
import javax.persistence.Table;
@Entity
@Table(name = "CAR")
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(name = "findByYearProcedure", procedureName = "FIND_CAR_BY_YEAR", resultClasses = { Car.class }, parameters = { @StoredProcedureParameter(name = "p_year", type = Integer.class, mode = ParameterMode.IN) }) })
public class Car {
private long id;
private String model;
private Integer year;
public Car(final String model, final Integer year) {
this.model = model;
this.year = year;
}
public Car() {
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", unique = true, nullable = false, scale = 0)
public long getId() {
return id;
}
public void setId(final long id) {
this.id = id;
}
@Column(name = "MODEL")
public String getModel() {
return model;
}
public void setModel(final String model) {
this.model = model;
}
@Column(name = "YEAR")
public Integer getYear() {
return year;
}
public void setYear(final Integer year) {
this.year = year;
}
}
@@ -0,0 +1,28 @@
package com.baeldung.jpa.model;
import java.util.HashMap;
import java.util.Map;
public class QueryParameter {
private Map<String, Object> parameters = null;
private QueryParameter(final String name, final Object value) {
this.parameters = new HashMap<>();
this.parameters.put(name, value);
}
public static QueryParameter with(final String name, final Object value) {
return new QueryParameter(name, value);
}
public QueryParameter and(final String name, final Object value) {
this.parameters.put(name, value);
return this;
}
public Map<String, Object> parameters() {
return this.parameters;
}
}
@@ -0,0 +1,43 @@
package com.baeldung.jpa.primarykeys;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
@Entity
@IdClass(AccountId.class)
public class Account {
@Id
private String accountNumber;
@Id
private String accountType;
private String description;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public String getAccountType() {
return accountType;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@@ -0,0 +1,52 @@
package com.baeldung.jpa.primarykeys;
import java.io.Serializable;
public class AccountId implements Serializable {
private static final long serialVersionUID = 1L;
private String accountNumber;
private String accountType;
public AccountId() {
}
public AccountId(String accountNumber, String accountType) {
this.accountNumber = accountNumber;
this.accountType = accountType;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((accountNumber == null) ? 0 : accountNumber.hashCode());
result = prime * result + ((accountType == null) ? 0 : accountType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AccountId other = (AccountId) obj;
if (accountNumber == null) {
if (other.accountNumber != null)
return false;
} else if (!accountNumber.equals(other.accountNumber))
return false;
if (accountType == null) {
if (other.accountType != null)
return false;
} else if (!accountType.equals(other.accountType))
return false;
return true;
}
}
@@ -0,0 +1,34 @@
package com.baeldung.jpa.primarykeys;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
public class Book {
@EmbeddedId
private BookId bookId;
private String description;
public Book() {
}
public Book(BookId bookId) {
this.bookId = bookId;
}
public BookId getBookId() {
return bookId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@@ -0,0 +1,62 @@
package com.baeldung.jpa.primarykeys;
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class BookId implements Serializable {
private static final long serialVersionUID = 1L;
private String title;
private String language;
public BookId() {
}
public BookId(String title, String language) {
this.title = title;
this.language = language;
}
public String getTitle() {
return title;
}
public String getLanguage() {
return language;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((language == null) ? 0 : language.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BookId other = (BookId) obj;
if (language == null) {
if (other.language != null)
return false;
} else if (!language.equals(other.language))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
}
@@ -0,0 +1,43 @@
package com.baeldung.jpa.sqlresultsetmapping;
import javax.persistence.*;
@SqlResultSetMapping(
name="EmployeeResult",
entities={
@EntityResult(
entityClass = com.baeldung.jpa.sqlresultsetmapping.Employee.class,
fields={@FieldResult(name="id",column="employeeNumber"),
@FieldResult(name="name", column="name")}
)
}
)
@NamedNativeQuery(
name="Employees",
query="SELECT id as employeeNumber, name FROM EMPLOYEE",
resultSetMapping = "EmployeeResult"
)
@Entity
public class Employee {
@Id
private Long id;
private String name;
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;
}
}
@@ -0,0 +1,58 @@
package com.baeldung.jpa.sqlresultsetmapping;
import javax.persistence.*;
@SqlResultSetMappings(value = {
@SqlResultSetMapping(name = "ScheduleResult",
classes = { @ConstructorResult(targetClass = com.baeldung.jpa.sqlresultsetmapping.ScheduledDay.class,
columns = { @ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "employeeId", type = Long.class),
@ColumnResult(name = "dayOfWeek") }) }),
@SqlResultSetMapping(name = "FridayEmployeeResult",
columns = { @ColumnResult(name = "employeeId") }),
@SqlResultSetMapping(name = "EmployeeScheduleResults",
entities = { @EntityResult(entityClass = com.baeldung.jpa.sqlresultsetmapping.Employee.class),
@EntityResult(entityClass = com.baeldung.jpa.sqlresultsetmapping.ScheduledDay.class)
}) })
@NamedNativeQuery(name = "FridayEmployees",
query = "SELECT employeeId FROM schedule_days WHERE dayOfWeek = 'FRIDAY'",
resultSetMapping = "FridayEmployeeResult")
@NamedNativeQuery(name = "Schedules",
query = "SELECT * FROM schedule_days WHERE employeeId = 3",
resultSetMapping = "ScheduleResult")
@Entity
@Table(name = "SCHEDULE_DAYS")
public class ScheduledDay {
@Id
@GeneratedValue
private Long id;
private Long employeeId;
private String dayOfWeek;
public ScheduledDay() {
}
public ScheduledDay(Long id, Long employeeId, String dayofWeek) {
this.id = id;
this.employeeId = employeeId;
this.dayOfWeek = dayofWeek;
}
public Long getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Long employeeId) {
this.employeeId = employeeId;
}
public String getDayOfWeek() {
return dayOfWeek;
}
public void setDayOfWeek(String dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}
}
@@ -0,0 +1,43 @@
package com.baeldung.jpa.stringcast;
import javax.persistence.*;
@SqlResultSetMapping(name = "textQueryMapping", classes = {
@ConstructorResult(targetClass = Message.class, columns = {
@ColumnResult(name = "text")
})
})
@Entity
public class Message {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String text;
public Message() {
}
public Message(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
@@ -0,0 +1,37 @@
package com.baeldung.jpa.stringcast;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.Query;
public class QueryExecutor {
public static List<String[]> executeNativeQueryNoCastCheck(String statement, EntityManager em) {
Query query = em.createNativeQuery(statement);
return query.getResultList();
}
public static List<String[]> executeNativeQueryWithCastCheck(String statement, EntityManager em) {
Query query = em.createNativeQuery(statement);
List results = query.getResultList();
if (results.isEmpty()) {
return new ArrayList<>();
}
if (results.get(0) instanceof String) {
return ((List<String>) results).stream().map(s -> new String[] { s }).collect(Collectors.toList());
} else {
return (List<String[]>) results;
}
}
public static <T> List<T> executeNativeQueryGeneric(String statement, String mapping, EntityManager em) {
Query query = em.createNativeQuery(statement, mapping);
return query.getResultList();
}
}
@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="java-jpa-scheduled-day">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.sqlresultsetmapping.ScheduledDay</class>
<class>com.baeldung.jpa.sqlresultsetmapping.Employee</class>
<class>com.baeldung.jpa.basicannotation.Course</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'classpath:database.sql'" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<!--<property name="hibernate.hbm2ddl.auto" value="create-drop" /> -->
<property name="show_sql" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
</properties>
</persistence-unit>
<persistence-unit name="jpa-h2">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.stringcast.Message</class>
<class>com.baeldung.jpa.enums.Article</class>
<class>com.baeldung.jpa.enums.CategoryConverter</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="show_sql" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
</properties>
</persistence-unit>
<persistence-unit name="jpa-db">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.model.Car</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://127.0.0.1:3306/baeldung" />
<property name="javax.persistence.jdbc.user"
value="baeldung" />
<property name="javax.persistence.jdbc.password"
value="YourPassword" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
<persistence-unit name="entity-graph-pu"
transaction-type="RESOURCE_LOCAL">
<class>com.baeldung.jpa.entitygraph.model.Post</class>
<class>com.baeldung.jpa.entitygraph.model.User</class>
<class>com.baeldung.jpa.entitygraph.model.Comment</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!--H2 -->
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:entitygraphdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" />
<property
name="javax.persistence.schema-generation.database.action"
value="drop-and-create" />
<property name="javax.persistence.sql-load-script-source"
value="data-init.sql" />
</properties>
</persistence-unit>
<persistence-unit name="java8-datetime-postgresql"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.baeldung.jpa.datetime.JPA22DateTimeEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/java8-datetime2" />
<property name="javax.persistence.jdbc.user"
value="postgres" />
<property name="javax.persistence.jdbc.password"
value="postgres" />
<property
name="javax.persistence.schema-generation.database.action"
value="drop-and-create" />
<!-- configure logging -->
<property name="eclipselink.logging.level" value="INFO" />
<property name="eclipselink.logging.level.sql" value="FINE" />
<property name="eclipselink.logging.parameters" value="true" />
</properties>
</persistence-unit>
<persistence-unit name="jpa-entity-definition">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.entity.Student</class>
<class>com.baeldung.jpa.primarykeys.Book</class>
<class>com.baeldung.jpa.primarykeys.BookId</class>
<class>com.baeldung.jpa.primarykeys.Account</class>
<class>com.baeldung.jpa.primarykeys.AccountId</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="show_sql" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
</properties>
</persistence-unit>
</persistence>
@@ -0,0 +1,8 @@
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `FIND_CAR_BY_YEAR`(in p_year int)
begin
SELECT ID, MODEL, YEAR
FROM CAR
WHERE YEAR = p_year;
end$$
DELIMITER ;
@@ -0,0 +1,6 @@
CREATE TABLE `car` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`MODEL` varchar(50) NOT NULL,
`YEAR` int(4) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
@@ -0,0 +1,5 @@
INSERT INTO CAR (ID, MODEL, YEAR) VALUES ('123456', 'Camaro', '2012');
INSERT INTO CAR (ID, MODEL, YEAR) VALUES ('12112', 'Fiat Panda', '2000');
INSERT INTO CAR (ID, MODEL, YEAR) VALUES ('111000', 'Fiat Punto', '2007');
INSERT INTO CAR (ID, MODEL, YEAR) VALUES ('3382', 'Citroen C3', '2009');
commit;
@@ -0,0 +1,8 @@
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (1,'user1','user1@test.com');
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (2,'user2','user2@test.com');
INSERT INTO `USER` (`ID`,`NAME`,`EMAIL`) VALUES (3,'user3','user3@test.com');
INSERT INTO `POST` (`ID`,`SUBJECT`,`USER_ID`) VALUES (1,'JPA Entity Graph In Action',1);
INSERT INTO `COMMENT` (`ID`,`REPLY`,`POST_ID`,`USER_ID`) VALUES (1,'Nice !!',1,2);
INSERT INTO `COMMENT` (`ID`,`REPLY`,`POST_ID`,`USER_ID`) VALUES (2,'Cool !!',1,3);
@@ -0,0 +1,21 @@
CREATE TABLE EMPLOYEE
(id BIGINT,
name VARCHAR(10));
INSERT INTO EMPLOYEE VALUES (1, 'JOHN');
INSERT INTO EMPLOYEE VALUES (2, 'MARY');
INSERT INTO EMPLOYEE VALUES (3, 'FRANK');
CREATE TABLE SCHEDULE_DAYS
(id IDENTITY,
employeeId BIGINT,
dayOfWeek VARCHAR(10));
INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (1, 'FRIDAY');
INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (2, 'SATURDAY');
INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'MONDAY');
INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'FRIDAY');
CREATE TABLE COURSE
(id BIGINT,
name VARCHAR(10));
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,54 @@
package com.baeldung.jpa.basicannotation;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class BasicAnnotationIntegrationTest {
private static EntityManager entityManager;
private static EntityManagerFactory entityManagerFactory;
@BeforeClass
public static void setup() {
entityManagerFactory = Persistence.createEntityManagerFactory("java-jpa-scheduled-day");
entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
}
@Test
public void givenACourse_whenCourseNamePresent_shouldPersist() {
Course course = new Course();
course.setName("Computers");
entityManager.persist(course);
entityManager.flush();
entityManager.clear();
}
@Test(expected = PersistenceException.class)
public void givenACourse_whenCourseNameAbsent_shouldFail() {
Course course = new Course();
entityManager.persist(course);
entityManager.flush();
entityManager.clear();
}
@AfterClass
public static void destroy() {
if (entityManager != null) {
entityManager.close();
}
if (entityManagerFactory != null) {
entityManagerFactory.close();
}
}
}
@@ -0,0 +1,89 @@
package com.baeldung.jpa.entity;
import static org.junit.Assert.assertEquals;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class StudentEntityIntegrationTest {
private EntityManagerFactory emf;
private EntityManager em;
@Before
public void setup() {
emf = Persistence.createEntityManagerFactory("jpa-entity-definition");
em = emf.createEntityManager();
}
@Test
public void persistStudentThenRetrieveTheDetails() {
Student student = createStudentWithRelevantDetails();
persist(student);
clearThePersistenceContext();
List<Student> students = getStudentsFromTable();
checkAssertionsWith(students);
}
@After
public void destroy() {
if (em != null) {
em.close();
}
if (emf != null) {
emf.close();
}
}
private void clearThePersistenceContext() {
em.clear();
}
private void checkAssertionsWith(List<Student> students) {
assertEquals(1, students.size());
Student john = students.get(0);
assertEquals(1L, john.getId().longValue());
assertEquals(null, john.getAge());
assertEquals("John", john.getName());
}
private List<Student> getStudentsFromTable() {
String selectQuery = "SELECT student FROM Student student";
TypedQuery<Student> selectFromStudentTypedQuery = em.createQuery(selectQuery, Student.class);
List<Student> students = selectFromStudentTypedQuery.getResultList();
return students;
}
private void persist(Student student) {
em.getTransaction().begin();
em.persist(student);
em.getTransaction().commit();
}
private Student createStudentWithRelevantDetails() {
Student student = new Student();
student.setAge(20); // the 'age' field has been annotated with @Transient
student.setName("John");
Date date = getDate();
student.setBirthDate(date);
student.setGender(Gender.MALE);
return student;
}
private Date getDate() {
LocalDate localDate = LocalDate.of(2008, 7, 20);
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
}
@@ -0,0 +1,68 @@
package com.baeldung.jpa.entitygraph.repo;
import com.baeldung.jpa.entitygraph.model.Comment;
import com.baeldung.jpa.entitygraph.model.Post;
import com.baeldung.jpa.entitygraph.model.User;
import org.hibernate.LazyInitializationException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class PostRepositoryIntegrationTest {
private static PostRepository postRepository = null;
@BeforeClass
public static void once() {
postRepository = new PostRepository();
}
@Test(expected = LazyInitializationException.class)
public void find() {
Post post = postRepository.find(1L);
assertNotNull(post.getUser());
String email = post.getUser().getEmail();
assertNull(email);
}
@Test
public void findWithEntityGraph() {
Post post = postRepository.findWithEntityGraph(1L);
assertNotNull(post.getUser());
String email = post.getUser().getEmail();
assertNotNull(email);
}
@Test(expected = LazyInitializationException.class)
public void findWithEntityGraph_Comment_Without_User() {
Post post = postRepository.findWithEntityGraph(1L);
assertNotNull(post.getUser());
String email = post.getUser().getEmail();
assertNotNull(email);
assertNotNull(post.getComments());
assertEquals(post.getComments().size(), 2);
Comment comment = post.getComments().get(0);
assertNotNull(comment);
User user = comment.getUser();
user.getEmail();
}
@Test
public void findWithEntityGraph2_Comment_With_User() {
Post post = postRepository.findWithEntityGraph2(1L);
assertNotNull(post.getComments());
assertEquals(post.getComments().size(), 2);
Comment comment = post.getComments().get(0);
assertNotNull(comment);
User user = comment.getUser();
assertNotNull(user);
assertEquals(user.getEmail(), "user2@test.com");
}
@AfterClass
public static void destroy() {
postRepository.clean();
}
}
@@ -0,0 +1,118 @@
package com.baeldung.jpa.enums;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ArticleUnitTest {
private static EntityManager em;
private static EntityManagerFactory emFactory;
@BeforeClass
public static void setup() {
Map properties = new HashMap();
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.format_sql", "true");
emFactory = Persistence.createEntityManagerFactory("jpa-h2", properties);
em = emFactory.createEntityManager();
}
@Test
public void shouldPersistStatusEnumOrdinalValue() {
// given
Article article = new Article();
article.setId(1);
article.setTitle("ordinal title");
article.setStatus(Status.OPEN);
// when
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(article);
tx.commit();
// then
Article persistedArticle = em.find(Article.class, 1);
assertEquals(1, persistedArticle.getId());
assertEquals("ordinal title", persistedArticle.getTitle());
assertEquals(Status.OPEN, persistedArticle.getStatus());
}
@Test
public void shouldPersistTypeEnumStringValue() {
// given
Article article = new Article();
article.setId(2);
article.setTitle("string title");
article.setType(Type.EXTERNAL);
// when
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(article);
tx.commit();
// then
Article persistedArticle = em.find(Article.class, 2);
assertEquals(2, persistedArticle.getId());
assertEquals("string title", persistedArticle.getTitle());
assertEquals(Type.EXTERNAL, persistedArticle.getType());
}
@Test
public void shouldPersistPriorityIntValue() {
// given
Article article = new Article();
article.setId(3);
article.setTitle("callback title");
article.setPriority(Priority.HIGH);
// when
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(article);
tx.commit();
// then
Article persistedArticle = em.find(Article.class, 3);
assertEquals(3, persistedArticle.getId());
assertEquals("callback title", persistedArticle.getTitle());
assertEquals(Priority.HIGH, persistedArticle.getPriority());
}
@Test
public void shouldPersistCategoryEnumConvertedValue() {
// given
Article article = new Article();
article.setId(4);
article.setTitle("converted title");
article.setCategory(Category.MUSIC);
// when
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(article);
tx.commit();
// then
Article persistedArticle = em.find(Article.class, 4);
assertEquals(4, persistedArticle.getId());
assertEquals("converted title", persistedArticle.getTitle());
assertEquals(Category.MUSIC, persistedArticle.getCategory());
}
}
@@ -0,0 +1,118 @@
package com.baeldung.jpa.primarykeys;
import static org.junit.Assert.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.baeldung.jpa.primarykeys.Account;
import com.baeldung.jpa.primarykeys.AccountId;
import com.baeldung.jpa.primarykeys.Book;
import com.baeldung.jpa.primarykeys.BookId;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class CompositeKeysIntegrationTest {
private static final String SAVINGS_ACCOUNT = "Savings";
private static final String ACCOUNT_NUMBER = "JXSDF324234";
private static final String ENGLISH = "English";
private static final String WAR_AND_PEACE = "War and Peace";
private static EntityManagerFactory emf;
private static EntityManager em;
@BeforeClass
public static void setup() {
emf = Persistence.createEntityManagerFactory("jpa-entity-definition");
em = emf.createEntityManager();
}
@Test
public void persistBookWithCompositeKeyThenRetrieveDetails() {
Book warAndPeace = createBook();
persist(warAndPeace);
clearThePersistenceContext();
Book book = findBookByBookId();
verifyAssertionsWith(book);
}
@Test
public void persistAccountWithCompositeKeyThenRetrieveDetails() {
Account savingsAccount = createAccount();
persist(savingsAccount);
clearThePersistenceContext();
Account account = findAccountByAccountId();
verifyAssertionsWith(account);
}
@AfterClass
public static void destroy() {
if (em != null) {
em.close();
}
if (emf != null) {
emf.close();
}
}
private Account createAccount() {
Account savingsAccount = new Account();
savingsAccount.setAccountNumber(ACCOUNT_NUMBER);
savingsAccount.setAccountType(SAVINGS_ACCOUNT);
savingsAccount.setDescription("Savings account");
return savingsAccount;
}
private void verifyAssertionsWith(Account account) {
assertEquals(ACCOUNT_NUMBER, account.getAccountNumber());
assertEquals(SAVINGS_ACCOUNT, account.getAccountType());
}
private Account findAccountByAccountId() {
return em.find(Account.class, new AccountId(ACCOUNT_NUMBER, SAVINGS_ACCOUNT));
}
private void persist(Account account) {
em.getTransaction()
.begin();
em.persist(account);
em.getTransaction()
.commit();
}
private Book findBookByBookId() {
return em.find(Book.class, new BookId(WAR_AND_PEACE, ENGLISH));
}
private Book createBook() {
BookId bookId = new BookId(WAR_AND_PEACE, ENGLISH);
Book warAndPeace = new Book(bookId);
warAndPeace.setDescription("Novel and Historical Fiction");
return warAndPeace;
}
private void verifyAssertionsWith(Book book) {
assertNotNull(book);
assertNotNull(book.getBookId());
assertEquals(WAR_AND_PEACE, book.getBookId()
.getTitle());
assertEquals(ENGLISH, book.getBookId()
.getLanguage());
}
private void persist(Book book) {
em.getTransaction()
.begin();
em.persist(book);
em.getTransaction()
.commit();
}
private void clearThePersistenceContext() {
em.clear();
}
}
@@ -0,0 +1,70 @@
package com.baeldung.jpa.sqlresultsetmapping;
import static org.junit.Assert.*;
import org.junit.jupiter.api.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.util.Collections;
import java.util.List;
public class SqlResultSetMappingUnitTest {
private static EntityManager em;
private static EntityManagerFactory emFactory;
@BeforeAll
public static void setup() {
emFactory = Persistence.createEntityManagerFactory("java-jpa-scheduled-day");
em = emFactory.createEntityManager();
}
@Test
public void whenNamedQuery_thenColumnResult() {
List<Long> employeeIds = em.createNamedQuery("FridayEmployees").getResultList();
assertEquals(2, employeeIds.size());
}
@Test
public void whenNamedQuery_thenConstructorResult() {
List<ScheduledDay> scheduleDays = Collections.checkedList(em.createNamedQuery("Schedules", ScheduledDay.class).getResultList(), ScheduledDay.class);
assertEquals(2, scheduleDays.size());
assertTrue(scheduleDays.stream().allMatch(c -> c.getEmployeeId().longValue() == 3));
}
@Test
public void whenNamedQuery_thenSingleEntityResult() {
List<Employee> employees = Collections.checkedList(em.createNamedQuery("Employees").getResultList(), Employee.class);
assertEquals(3, employees.size());
assertTrue(employees.stream().allMatch(c -> c.getClass() == Employee.class));
}
@Test
public void whenNamedQuery_thenMultipleEntityResult() {
final Query query = em.createNativeQuery("SELECT e.id, e.name, d.id, d.employeeId, d.dayOfWeek "
+ " FROM employee e, schedule_days d "
+ " WHERE e.id = d.employeeId", "EmployeeScheduleResults");
List<Object[]> results = query.getResultList();
assertEquals(4, results.size());
assertTrue(results.get(0).length == 2);
Employee emp = (Employee) results.get(1)[0];
ScheduledDay day = (ScheduledDay) results.get(1)[1];
assertTrue(day.getEmployeeId() == emp.getId());
}
@AfterAll
public static void destroy() {
if (em != null) {
em.close();
}
if (emFactory != null) {
emFactory.close();
}
}
}
@@ -0,0 +1,76 @@
package com.baeldung.jpa.storedprocedure;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.ParameterMode;
import javax.persistence.Persistence;
import javax.persistence.StoredProcedureQuery;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.baeldung.jpa.model.Car;
public class StoredProcedureLiveTest {
private static EntityManagerFactory factory = null;
private static EntityManager entityManager = null;
@BeforeClass
public static void init() {
factory = Persistence.createEntityManagerFactory("jpa-db");
entityManager = factory.createEntityManager();
}
@Before
public void setup() {
}
@Test
public void createCarTest() {
final EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
final Car car = new Car("Fiat Marea", 2015);
entityManager.persist(car);
transaction.commit();
} catch (final Exception e) {
System.out.println(e.getCause());
if (transaction.isActive()) {
transaction.rollback();
}
}
}
@Test
public void findCarsByYearNamedProcedure() {
final StoredProcedureQuery findByYearProcedure = entityManager.createNamedStoredProcedureQuery("findByYearProcedure");
final StoredProcedureQuery storedProcedure = findByYearProcedure.setParameter("p_year", 2015);
storedProcedure.getResultList()
.forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear()));
}
@Test
public void findCarsByYearNoNamed() {
final StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("FIND_CAR_BY_YEAR", Car.class)
.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
.setParameter(1, 2015);
storedProcedure.getResultList()
.forEach(c -> Assert.assertEquals(new Integer(2015), ((Car) c).getYear()));
}
@AfterClass
public static void destroy() {
if (entityManager != null) {
entityManager.close();
}
if (factory != null) {
factory.close();
}
}
}
@@ -0,0 +1,53 @@
package com.baeldung.jpa.stringcast;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.persistence.*;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class SpringCastUnitTest {
private static EntityManager em;
private static EntityManagerFactory emFactory;
@BeforeClass
public static void setup() {
emFactory = Persistence.createEntityManagerFactory("jpa-h2");
em = emFactory.createEntityManager();
// insert an object into the db
Message message = new Message();
message.setText("text");
EntityTransaction tr = em.getTransaction();
tr.begin();
em.persist(message);
tr.commit();
}
@Test(expected = ClassCastException.class)
public void givenExecutorNoCastCheck_whenQueryReturnsOneColumn_thenClassCastThrown() {
List<String[]> results = QueryExecutor.executeNativeQueryNoCastCheck("select text from message", em);
// fails
for (String[] row : results) {
// do nothing
}
}
@Test
public void givenExecutorWithCastCheck_whenQueryReturnsOneColumn_thenNoClassCastThrown() {
List<String[]> results = QueryExecutor.executeNativeQueryWithCastCheck("select text from message", em);
assertEquals("text", results.get(0)[0]);
}
@Test
public void givenExecutorGeneric_whenQueryReturnsOneColumn_thenNoClassCastThrown() {
List<Message> results = QueryExecutor.executeNativeQueryGeneric("select text from message", "textQueryMapping", em);
assertEquals("text", results.get(0).getText());
}
}
@@ -0,0 +1,3 @@
INSERT INTO employee (1, "JOHN");
INSERT INTO employee (2, "MARY");
INSERT INTO employee (3, "FRANK");
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="jpa-db">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.model.Car</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/baeldung" />
<property name="javax.persistence.jdbc.user" value="baeldung" />
<property name="javax.persistence.jdbc.password" value="YourPassword" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
<persistence-unit name="jpa-h2">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.stringcast.Message</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="show_sql" value="true"/>
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
</properties>
</persistence-unit>
</persistence>
@@ -0,0 +1,10 @@
INSERT INTO SCHEDULE_DAYS (1, 13, 21, 'FRIDAY');
INSERT INTO SCHEDULE_DAYS (2, 8, 4, 'SATURDAY');
INSERT INTO SCHEDULE_DAYS (3, 8, 4, 'FRIDAY');
-- private Long id;
-- private Long employeeId;
-- private Time in;
-- private Time out;
-- private DayOfWeek dayOfWeek;