I keep receiving this error: Error creating bean with name 'entityManagerFactory' (Ive tried every annotation known to man(#ComponentScan, #EnableJPARepositorires #EntityScan) and tried reinstalling/removing jars/versions that may be conflicting. It seems for some reason Spring just cant configure the bean properly any suggestions?
model class:
package com.example.demo.models;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.stereotype.Component;
#Entity
#Table(name="Strain")
#Component
public class Strain {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="strain_id")
private int id;
private String name;
private String StrainType;
private Set<Strain> parents;
public Strain() {
super();
// TODO Auto-generated constructor stub
}
public Strain(int id, String name, String strainType, Set<Strain> parents) {
super();
this.id = id;
this.name = name;
StrainType = strainType;
this.parents = parents;
}
public Strain(String name, String strainType, Set<Strain> parents) {
super();
this.name = name;
StrainType = strainType;
this.parents = parents;
}
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;
}
public String getStrainType() {
return StrainType;
}
public void setStrainType(String strainType) {
StrainType = strainType;
}
public Set<Strain> getParents() {
return parents;
}
public void setParents(Set<Strain> parents) {
this.parents = parents;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((StrainType == null) ? 0 : StrainType.hashCode());
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((parents == null) ? 0 : parents.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;
Strain other = (Strain) obj;
if (StrainType == null) {
if (other.StrainType != null)
return false;
} else if (!StrainType.equals(other.StrainType))
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (parents == null) {
if (other.parents != null)
return false;
} else if (!parents.equals(other.parents))
return false;
return true;
}
#Override
public String toString() {
return "Strain [id=" + id + ", name=" + name + ", StrainType=" + StrainType + ", parents=" + parents + "]";
}
}
controller:
package com.example.demo.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.models.Strain;
import com.example.demo.services.StrainService;
#RestController
public class StrainController {
#Autowired
private StrainService ss;
#GetMapping(value = "/strains")
#ResponseBody
public List<Strain> findAll() {
return ss.findAll();
}
#GetMapping("/strains/{id}")
#ResponseBody
public ResponseEntity<Strain> findById(#PathVariable("id") int id) {
Strain m = ss.findById(id);
return ResponseEntity.status(HttpStatus.OK).body(m);
}
#PostMapping("/strain")
#ResponseBody
public ResponseEntity<Strain> save(#RequestBody Strain m) {
return ResponseEntity.ok(ss.save(m));
}
#DeleteMapping("/strain")
#ResponseBody
public ResponseEntity<Strain> deleteByName(#RequestBody String name) {
return ResponseEntity.ok(ss.deleteByName(name));
}
}
ServiceClass:
package com.example.demo.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.example.demo.models.Strain;
import com.example.demo.repositories.StrainRepository;
#Service
public class StrainService {
#Autowired
private StrainRepository dao;
public Strain save(Strain s){
return dao.save(s);
}
public void delete(Strain s){
dao.delete(s);
}
public Strain findById(int id) {
return dao.findById(id);
}
public List<Strain> findAll() {
return dao.findAll();
}
public Strain findByName(String name) {
return dao.findByName(name);
}
public int findIdByName(String name) {
return dao.findIdByName(name);
}
public Strain deleteByName(String name) {
return dao.deleteByName(name);
}
public List<Strain> findAllByStrainType(String name){
return dao.findAllByStrainType(name);
}
public boolean existStrainByName(String name) {
return dao.existStrainByName(name);
}
}
repo class:
package com.example.demo.repositories;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.models.Strain;
#Repository
public interface StrainRepository extends JpaRepository<Strain, Integer> {
public Strain save(Strain s);
public void delete(Strain s);
public Strain findById(int id);
public Strain findByName(String name);
public Strain deleteByName(String name);
public List<Strain> findAll();
public List<Strain> findAllByStrainType(String name);
public boolean existStrainByName(String name);
public int findIdByName(String name);
}
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>Weedepedia2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Weedepedia2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Alpha5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
it seems to be hibernate related because when i remove the #Entity annotation it goes to another error that has to do with the class not being managed for persistence
In order to get the EntityManagerFactory auto-configured by Spring Boot you need to use spring-boot-starter-data-jpa dependency. In your case, you are using plain spring-data-jpa
Replace
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.0.Alpha5</version>
</dependency>
With
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
And make sure you have the database connection details in your application properties file.
Please see below a snippet of application.yml for PostgreSQL connection
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: postgres
Update
Also as #Mohammad Al Alwa pointed out the entity mapping doesn't look good. A typical case would be the entity has a reference to one parent.
In your case that would be
#OneToOne
private Strain parent;
And in the StrainRepository you need to change
public boolean existStrainByName(String name);
To
public boolean existsByName(String name);
Please note you could generate database tables out of your entities if you provide spring.jpa.hibernate.ddl-auto property
Please see below
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/postgres
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: create-only
Hibernate fails to map the entity to a table because you're using a collection field Set<Strain> parents without defining the relationship mapping (ie. #OneToMany or #ManyToMany).
Also, it's not recommended to use a native type int for the id.
Related
I have the following problem. I have a simple Spring Boot Application that is supposed to process the debts of users. The service does compile, but neither a PostRequest to insert a new record nor a GetRequest to display the debt of a user works. When the service is started, the application automatically creates the appropriate table for the entity. Therefore I assume that the database connection will not be the problem. It looks like my service does not recognize the RestController. With Postman I keep getting the error code "404 Not Found".
Does anyone have any idea what I am doing wrong?
My Entity
package Entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
#Entity
#Table(name= "debts")
#EnableAutoConfiguration
public class DebtsEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "user_id")
private String userId;
#Column(name = "invoice_id")
private int invoiceId ;
#Column(name = "creditor")
private String creditor;
#Column(name = "amount")
private double amount;
#Column(name = "deadline")
private String deadline;
#Column(name = "installment")
private double installment;
public DebtsEntity(){
}
public DebtsEntity(int id, String userId, int invoiceId, String creditor, double amount, String deadline,
double installment) {
super();
this.id = id;
this.userId = userId;
this.invoiceId = invoiceId;
this.creditor = creditor;
this.amount = amount;
this.deadline = deadline;
this.installment = installment;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public int getInvoiceId() {
return invoiceId;
}
public void setInvoiceId(int invoiceId) {
this.invoiceId = invoiceId;
}
public String getCreditor() {
return creditor;
}
public void setCreditor(String creditor) {
this.creditor = creditor;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getDeadline() {
return deadline;
}
public void setDeadline(String deadline) {
this.deadline = deadline;
}
public double getInstallment() {
return installment;
}
public void setInstallment(double installment) {
this.installment = installment;
}
#Override
public String toString() {
return "debtsEntity [id=" + id + ", userId=" + userId + ", invoiceId=" + invoiceId + ", creditor=" + creditor
+ ", amount=" + amount + ", deadline=" + deadline + ", installment=" + installment + "]";
}
}
My RestController
package Controller;
import java.net.URI;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import DAO.DebtsDAO;
import Entity.DebtsEntity;
#RestController
public class DebtsController {
#Autowired
DebtsDAO debtsDAO;
#GetMapping("/{userId}/debts")
public List<DebtsEntity> retrieveDebtsByUserId(#PathVariable String userId)
{
List<DebtsEntity> debts = debtsDAO.findByUserId(userId);
return debts;
}
#PostMapping("/debts")
public ResponseEntity<Object> createInvoice(#RequestBody DebtsEntity debtsEntity)
{
DebtsEntity savedUser =debtsDAO.save(debtsEntity);
URI location= ServletUriComponentsBuilder.fromCurrentRequest()
.path("path/{id}")
.buildAndExpand(savedUser.getId()).toUri();
return ResponseEntity.created(location).build();
}
}
My DAO
package DAO;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import Entity.DebtsEntity;
#Component
public interface DebtsDAO extends JpaRepository<DebtsEntity, Integer>{
List<DebtsEntity> findByUserId(String user_id);
}
My application.properties
## Database konfiguration
spring.datasource.url=jdbc:postgresql://localhost:5432/Test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=create
# define if Database Queries should be written in logfile
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.default_schema=public
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL81Dialect
server.port=8000
spring.application.name=Debts
My dependencies
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>LifeOps</groupId>
<artifactId>Service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
UPDATE 1
Get-Request
URL: http://localhost:8000/1000/depts
PostRequest
URL: http://localhost:8000/depts
RequestBody:
{
"id":1000,
"user_id": "ABC1234",
"invoice_id":100001,
"creator": "A12L",
"amount": 123012.56,
"deadline": "20.10.12",
"installment": 50.00
}
package Service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
#EntityScan(basePackages = "entity")
#SpringBootApplication
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
UPDATE 2
Class package
DebtsApplication service.debts
DebtsController service.debts.controller
DebtsEntity service.debts.entity
DebtsDAO service.debts.dao
I would suggest you add a base package (something like "com.doncarlito") and put ServiceApplication in it.
package com.doncarlito;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
#EntityScan(basePackages = "entity")
#SpringBootApplication
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
Then move all the other existent packages to be sub-packages of this one:
com.doncarlito.entity
com.doncarlito.dao
com.doncarlito.controller
com.doncarlito.service
The reason being that #SpringBootApplication encapsulates #Configuration, #EnableAutoConfiguration, and #ComponentScan annotations with their default attributes. The default value for #ComponentScan means that all the sub-packages on the package the #ComponentScan is used are scanned. That is why it is usually a good practice to include the main class in the base package of the project.
You are running your app from x.y.z.ApplicationService but your components are in different pacage like x.y.a.YourComponent which will NOT be picked up by the spring.
By default, spring scans package (and descendants) of your #SpringApplication class. In reference to the above it would be x.y.z.*.....
To solve your problem (alternatives)
Move your ApplicationService next to DebtsApplication so it will be "on top" of all required components (#RestController for example)
Add #ComponentScan(basePackgages={'service.debts'})
to ApplicationService so you will "manually" show spring where to look for components.
There are other ways, but you should be fine with those 2
before I explain the problem, I have gone through similar threads that result in the error I am facing. So I have looked and none of the solutions have been helpful, therefore, I am posting my own custom question. Creating a simple Spring Boot/MVC project I am getting this error:
Description:
Field cRepo in pack.website.controllers.LandingPageController required
a bean of type 'pack.website.repositories.CustomerRepository' that
could not be found.
The injection point has the following annotations:
#org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type
'pack.website.repositories.CustomerRepository' in your configuration.
after configuring my Controller class, and repo class. Below I will attach the codes and my main. Does anyone know why this error is still occurring? I've tried #component, #service (in my service class), #repository tag.... Still does not work. Please help:
#Controller
public class LandingPageController {
#Autowired
private CustomerRepository cRepo;
#GetMapping("")
public String viewLandingPage() {
return "index";
}
#GetMapping("/register")
public String showRegistrationForm(Model model) {
model.addAttribute("customer", new Customer());
return "signup_form";
}
#PostMapping("/process_register")
public String processRegister(Customer customer) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(customer.getPassword());
customer.setPassword(encodedPassword);
cRepo.save(customer);
return "register_success";
}
#GetMapping("/users")
public String listUsers(Model model) {
List<Customer> listUsers = cRepo.findAll();
model.addAttribute("listUsers", listUsers);
return "users";
}
}
#############
public interface CustomerRepository extends JpaRepository<Customer, Long>{
public Customer findByEmail(String email);
}
#############
public class CustomerService implements UserDetailsService {
#Autowired
private CustomerRepository cRepo;
#Override
public CustomerDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Customer customer = cRepo.findByEmail(username);
if (customer == null) {
throw new UsernameNotFoundException("User not found");
}
return new CustomerDetails(customer);
}
}
###########
#SpringBootApplication
#ComponentScan({"pack.website.controllers", "pack.website.repositories" })
public class ProjectApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
}
With Service Layer #Service annotation may help following is controller part
package com.example.jpalearner.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.jpalearner.jpa.JpaService;
import com.example.jpalearner.jpa.Studentinformation;
import com.example.jpalearner.service.StudentInfoService;
#RestController
public class RouterController {
#Autowired
StudentInfoService service;
#PostMapping(value = "/searchByservice")
public Studentinformation searchByservice(#RequestBody Studentinformation studentinformation)
{
try {
return service.fetchByName(studentinformation);
} catch (Exception e) {
System.err.println(e);
}
return null;
}
}
Service Interface
package com.example.jpalearner.service;
import com.example.jpalearner.jpa.Studentinformation;
public interface StudentInfoService {
public Studentinformation fetchByName(Studentinformation obj);
}
And the implementation
package com.example.jpalearner.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.jpalearner.jpa.JpaService;
import com.example.jpalearner.jpa.Studentinformation;
import com.example.jpalearner.service.StudentInfoService;
#Service
public class StudentInfoServiceImpl implements StudentInfoService {
#Autowired
private JpaService repos;
#Override
public Studentinformation fetchByName(Studentinformation obj) {
// TODO Auto-generated method stub
return repos.findByStudentname(obj.getStudentname());
}
}
If i miss #Service annotation then following error will occur
May be its not able to scan the package properly or you are missing #service tag in CustomerService.java , while check wether following code is usefull folowing is the ServletInitializer
package com.example.jpalearner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
#ComponentScan(basePackages = { "com.example.jpalearner" })
#SpringBootApplication
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ServletInitializer.class);
}
}
followed by RouterController
package com.example.jpalearner.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.jpalearner.jpa.JpaService;
import com.example.jpalearner.jpa.Studentinformation;
#RestController
public class RouterController {
#Autowired
private JpaService repos;
#GetMapping
public String defaultpath()
{
return "Hello World";
}
#PutMapping(value = "/save")
public Map<String, Object> SaveRecord(#RequestBody Studentinformation studentinformation) {
Map<String, Object> res = new HashMap<String, Object>();
try {
repos.save(studentinformation);
res.put("saved", true);
} catch (Exception e) {
res.put("Error", e);
}
return res;
}
#PostMapping(value = "/search")
public Studentinformation GetRecord(#RequestBody Studentinformation studentinformation)
{
try {
return repos.findByStudentname(studentinformation.getStudentname());
} catch (Exception e) {
System.err.println(e);
}
return null;
}
}
Interface to implement JPA
package com.example.jpalearner;
import org.springframework.data.repository.CrudRepository;
public interface JpaService extends CrudRepository<Studentinformation, Long> {
public Studentinformation findByStudentname(String email);
}
which uses entity class
package com.example.jpalearner.jpa;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Studentinformation {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long regid;
public Long getRegid() {
return regid;
}
public void setRegid(Long regid) {
this.regid = regid;
}
private String studentname;
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
}
application properties as following
## default connection pool
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
## PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/testjpa
spring.datasource.username=postgres
spring.datasource.password=xyz#123
Following is the pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.jpalearner</groupId>
<artifactId>simplejpalearner</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>simplejpasample</name>
<description>Demo project for Spring Boot, and jpa test</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I have not used #Service or #Repository tags(as repo is autowired in controller) , while i have just added base package name, hope it helps #throwawayaccount2020 while if you use an interface to work on Repository then #Service tag is required
#ComponentScan(basePackages = { "com.example.jpalearner" })
Sql
CREATE TABLE studentinformation
(
regid serial NOT NULL,
studentname character varying(250) NOT NULL
);
Filetree
I am in the process of learning Java spring Boot from the tutorial found here
I keep getting the "Field topicRepository in api.dataBase.basic.apiDatabase.Models.TopicService required a bean of type 'api.dataBase.basic.apiDatabase.Interface.TopicRepository' that could not be found."
I read that this error can occur because of componentScan is failing for poor annotation of the class or poor package layout.
Layout of my java packages
lay out of my project
My classes are the following;
package api.dataBase.basic.apiDatabase;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication ()
public class ApiDatabaseApplication {
public static void main(String[] args) {
SpringApplication.run(ApiDatabaseApplication.class, args);
}
}
Topic.java
package api.dataBase.basic.apiDatabase.Models;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Topic {
#Id
private String id;
private String name;
private String description;
//private Address address;
public Topic(final String id, final String name, final String description) {
this.id = id;
this.name = name;
this.description = description;
}
public Topic() {
}
#Id
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
}
TopicRepository.java
package api.dataBase.basic.apiDatabase.Interface;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import api.dataBase.basic.apiDatabase.Models.Topic;
#Repository
public interface TopicRepository extends CrudRepository <Topic, String>{
}
TopicService.java
package api.dataBase.basic.apiDatabase.Models;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import api.dataBase.basic.apiDatabase.Interface.TopicRepository;
#Service
public class TopicService {
#Autowired
private TopicRepository topicRepository;
private List<Topic> Oldtopics = new ArrayList<>(Arrays.asList(
new Topic("1001", "test", "hello 1"),
new Topic("1002", "hello", "hello 2")
));
public List<Topic> getTopics() {
List<Topic> topics = new ArrayList<>();
topicRepository.findAll().forEach(topics::add);
return topics;
}
public Topic getTopic(String id) {
return Oldtopics.stream().filter(t -> t.getId().equals(id)).findFirst().get();
}
public void addTopic(final Topic topic) {
topicRepository.save(topic);
}
public void updateTopic(final Topic topic, final String id) {
for (int i = 0; i < Oldtopics.size(); i++) {
if (Oldtopics.get(i).getId().equals(id)) {
Oldtopics.set(i, topic);
return;
}
}
}
public void deleteTopic(String id) {
Oldtopics.removeIf(t -> t.getId().equals(id));
}
public void deleteTopic(final String[] id) {
for (int i = 0; i < Oldtopics.size(); i++) {
for (String ids : id) {
if (Oldtopics.get(i).getId().equals(ids)) {
Oldtopics.remove(i);
}
}
}
}
}
Any help will be appreciated.
Full Stack Trace.
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-11-21 19:18:05.350 ERROR 4192 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field topicRepository in api.dataBase.basic.apiDatabase.Models.TopicService required a bean of type 'api.dataBase.basic.apiDatabase.Interface.TopicRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'api.dataBase.basic.apiDatabase.Interface.TopicRepository' in your configuration.
POM:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>api.dataBase.basic</groupId>
<artifactId>apiDatabase</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>apiDatabase</name>
<description>API project with JPA database</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This can be the case for missed configuration and thus messed component scan.
I'd suggest that you should add 'Config.java' with following content to your source root (src/main/java)
#Configuration
#EnableJpaRepositories
class Config {
}
I have simple and self-sufficient example below with four Java files. My question is how can I annotate the DTO class with #Component and inject it into controller class for reuse? Simple annotating the ResponseDto.java class with that annotation doesn't do anything.
First file is REST controller (Controller.java), second file is utility class (CountriesUtility.java) containing one list of strings with country codes and one method to check if given argument from the controller, country code, is present in the list of strings in this utility class. Third file is main application file (DemoForInjectionApplication.java) for running this Spring application. Last file is simple DTO class (ResponseDTO.java) used to create response JSON.
This code for POST request at "http://localhost:8080/controller/required_fields?country_code=PL" responds with {
"status": "OK",
"data": "Correct country!"
} and for POST request at "http://localhost:8080/controller/required_fields?country_code=NOSUCHCOUNTRY" responds with {
"status": "Error",
"data": ""
}
Controller.java
package com.examplead.demoforinjection;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("controller")
public class Controller {
#PostMapping(value = "/required_fields", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(code = HttpStatus.OK)
public #ResponseBody ResponseDto requiredFields(#RequestParam(name = "country_code") final String countryCode) {
/* How can I annotate the DTO class with #Component and inject it into this class for reuse? */
final ResponseDto responseDto;
responseDto = new CountriesCurrenciesUtility().isValidCountryAndCurrency(countryCode);
return responseDto;
}
}
CountriesUtility.java
package com.examplead.demoforinjection;
import java.util.Arrays;
import java.util.List;
public class CountriesCurrenciesUtility {
private static final List<String> COUNTRIES = Arrays.asList("BE", "GR", "RE", "PL");
public ResponseDto isValidCountryAndCurrency(final String countryCode) {
ResponseDto dto = new ResponseDto();
if (COUNTRIES.contains(countryCode)) {
dto.setData("Correct country!");
dto.setStatus("OK");
} else {
dto.setData("");
dto.setStatus("Error");
}
return dto;
}
}
DemoForInjectionApplication.java
package com.examplead.demoforinjection;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoForInjectionApplication {
public static void main(String[] args) {
SpringApplication.run(DemoForInjectionApplication.class, args);
}
}
ResponseDTO.java
package com.examplead.demoforinjection;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
public class ResponseDto {
/**
* Status of the request.
*/
#JsonProperty()
private String status;
/**
* Data of the request.
*/
#JsonProperty()
private String data;
#Override
public String toString() {
return "ResponseDto{" +
"status='" + status + '\'' +
", data='" + data + '\'' +
'}';
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ResponseDto that = (ResponseDto) o;
return Objects.equals(status, that.status) &&
Objects.equals(data, that.data);
}
#Override
public int hashCode() {
return Objects.hash(status, data);
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
pom.xml
Just in case somebody would like to run it locally, you will need to create packages manually. This is simple pom file, generated using Spring Initializr with "Rest Repositories WEB" and "Spring Web" dependencies with Java 11.
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.examplead</groupId>
<artifactId>demo-for-injection</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-for-injection</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Note: Data Transfer Objects are not meant for injection. They are used for transferring data from one layer to another. The response through DTOs may be same or different based on the APIs present in your application. So, it is better to create instance of DTO when required to send data from one layer to another.
You can do #Component on ResponseDto.
But this is a bad design and may lead to some unwanted response.
So, it is not recommend to annotate DTO with #Component based on the working definition of DTO.
You can follow this simple design.
Modify ResponseDTO.java and keep in the package com.examplead.demoforinjection.dto:
package com.examplead.demoforinjection.dto;
import java.io.Serializable;
public class ResponseDto implements Serializable {
/**
* default serial version ID
*/
private static final long serialVersionUID = 1L;
/**
* Status of the request.
*/
private String status;
/**
* Data of the request.
*/
private String data;
#Override
public String toString() {
return "ResponseDto{" +
"status='" + status + '\'' +
", data='" + data + '\'' +
'}';
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
Modify CountriesCurrenciesUtility.java and keep in the package com.examplead.demoforinjection.utility :
package com.examplead.demoforinjection.utility;
import java.util.Arrays;
import java.util.List;
import com.examplead.demoforinjection.dto.ResponseDto;
public final class CountriesCurrenciesUtility {
private static final List<String> COUNTRIES = Arrays.asList("BE", "GR", "RE", "PL");
public static ResponseDto isValidCountryAndCurrency(final String countryCode) {
ResponseDto dto = new ResponseDto();
if (COUNTRIES.contains(countryCode)) {
dto.setData("Correct country!");
dto.setStatus("OK");
} else {
dto.setData("No data found.");
dto.setStatus("Error");
}
return dto;
}
}
Modify Controller.java and keep in the package com.examplead.demoforinjection.controller :
package com.examplead.demoforinjection.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.examplead.demoforinjection.dto.ResponseDto;
import com.examplead.demoforinjection.utility.CountriesCurrenciesUtility;
#RestController
#RequestMapping("controller")
public class Controller {
#PostMapping(value = "/required_fields", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseDto> requiredFields(#RequestParam(name = "country_code") final String countryCode) {
ResponseDto responseDto = CountriesCurrenciesUtility.isValidCountryAndCurrency(countryCode);
if(responseDto.getStatus().equals("OK")) {
return new ResponseEntity<ResponseDto>(responseDto, HttpStatus.OK);
}
return new ResponseEntity<ResponseDto>(responseDto, HttpStatus.BAD_REQUEST);
}
}
Note : #RestController includes both #ResponseBody and #Controller. So, you don't need to use #ResponseBody separately.
As the accepted answer states, it's not a recommended way of doing things. However, there is a way of injecting dependencies into unmanaged classes (created with "new" operator).
There is #org.springframework.beans.factory.annotation.Configurable annotation, which is meant for that.
Reference:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Configurable.html
https://www.baeldung.com/spring-inject-bean-into-unmanaged-objects
Dependending on a scenario and architectural approach, it can do great things. Anemic domain objects is considered anti-pattern by some.
How can I save collection of value type in hibernate with annotations - List of String List<String> or for example:
#Entity
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
private Set<History> history;
}
and here is value type:
public class History {
private String someAttribute;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((entry == null) ? 0 : entry.hashCode());
result = prime * result + ((entryDate == null) ? 0 : entryDate.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;
History other = (History) obj;
if (entry == null) {
if (other.entry != null)
return false;
} else if (!entry.equals(other.entry))
return false;
if (entryDate == null) {
if (other.entryDate != null)
return false;
} else if (!entryDate.equals(other.entryDate))
return false;
return true;
}
}
Can anyone give some example with hibernate annotations?
For an entity to have collection value type, we need to create a separate table to hold this collection as single row of the entity will have multiple values of for this collection. Use #ElementCollection and #CollectionTable annotations on the collection value attribute.
#ElementCollection
#CollectionTable(name = "STUDENT_HISTORY", joinColumns = {#JoinColumn(name = STUDENT_ID) })
#Column(name="HISTORY")
private Set<History> history;
The table will hold the collection values in the column HISTORY and uses STUDENT_ID column as the join column which will be the foreign key to the ID of student.
Below is a complete example using native Hibernate (I mean without the JPA):
Student.java
package domain.app.data;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
#Entity
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#ElementCollection
#CollectionTable(name="STUDENT_HISTORY", joinColumns={#JoinColumn(name="STUDENT_ID", referencedColumnName="ID")})
#Column(name="HISTORY")
private Set<History> history = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<History> getHistory() {
return history;
}
public void setHistory(Set<History> history) {
this.history = history;
}
#Override
public String toString() {
return "Student [id=" + id + ", history=" + history + "]";
}
}
History.java
package domain.app.data;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class History {
#Column(name="HISTORY")
private String someAttribute;
public String getSomeAttribute() {
return someAttribute;
}
public void setSomeAttribute(String someAttribute) {
this.someAttribute = someAttribute;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((someAttribute == null) ? 0 : someAttribute.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;
History other = (History) obj;
if (someAttribute == null) {
if (other.someAttribute != null)
return false;
} else if (!someAttribute.equals(other.someAttribute))
return false;
return true;
}
}
HibernateUtil.java
package domain.app.data.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import domain.app.data.Student;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().build();
Configuration configuration = new Configuration();
configuration.addAnnotatedClass(Student.class);
return configuration.buildSessionFactory(serviceRegistry);
}
public static SessionFactory getSession() {
return sessionFactory;
}
}
Application.java
package domain.app;
import org.hibernate.Session;
import domain.app.data.History;
import domain.app.data.Student;
import domain.app.data.util.HibernateUtil;
public class Application {
public static void main(String[] args) {
Session session = HibernateUtil.getSession().openSession();
session.getTransaction().begin();
Student student = new Student();
History history1 = new History();
history1.setSomeAttribute("Volunteer since 2016");
History history2 = new History();
history2.setSomeAttribute("Football team member");
student.getHistory().add(history1);
student.getHistory().add(history2);
session.save(student);
session.getTransaction().commit();
session.close();
}
}
hibernate.properties
hibernate.connection.username=admin
hibernate.connection.password=password
hibernate.connection.url=jdbc:h2:~/h2db/test
hibernate.connection.driver_class=org.h2.Driver
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<configuration debug="false" scan="true" scanPeriod="30 minutes">
<appender name="Console-Appender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%gray(%d{yyyy-MM-dd HH:mm:ss.SSS}) %highlight(%5p) %gray(---) %magenta([%15.15t]) %cyan(%-40.40c{1}) %black(:) %m%n%xEx</pattern>
</encoder>
</appender>
<root level="trace">
<appender-ref ref="Console-Appender" />
</root>
</configuration>
pom.xml
<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>
<groupId>stackoverflow</groupId>
<artifactId>SO-41248001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.5.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
</project>
Project Structure:
Result in DB:
try this it should work.
#Entity
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#ElementCollection
private Collection Set<History> history;
}
#Embeddable
public class History {
private String someAttribute;
......
}