I am new to Spring Boot framework and lombok.
I defined my entity like that:
#Entity
#Table(name = "student")
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
public class Student implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String firstName;
private String lastName;
private String email;
}
I also create a controller where I add the following:
#PostMapping(path="/add") // Map ONLY POST Requests
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
Student st = new Student();
st.setFirstName(name);
st.setEmail(email);
//studentservice.save(st);
return "Saved";
}
I dont know why I have a red line under setFirstName. They ask me to create this function in the student class.
I am using eclipse.
please follow the steps as below:
check pom.xml for lombok dependency
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
Now you can check your IDE,
I hope, it helps!
I am using spring boot 1.5.10 & spring rest to develop some rest services
I have relation one to many between product and services.
When I fill data in services table and access the service that get me all products(http://localhost:8080/user/products) give me this exception:
Caused by: java.lang.IllegalStateException: getOutputStream() has
already been called for this response.
and repeated json appear in the browser!
If services table is empty: no exception is thrown. I don't know why.
I found a link that discuss the problem but yet I couldn't solve it.
Product entity:
#Entity
#Table(name = "products")
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID")
private Integer id;
#Basic(optional = false)
#Column(name = "NAME")
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "productId")
private List<Service> servicesList;
}
Service Entity:
#Entity
#Table(name = "services")
public class Service implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID")
private Integer id;
#Basic(optional = false)
#Column(name = "NAME")
private String name;
#Basic(optional = false)
#Column(name = "TYPE")
private int type;
#JoinColumn(name = "PRODUCT_ID", referencedColumnName = "ID")
#ManyToOne(optional = false)
private Product productId;
}
And the ProductController
#Controller
#RequestMapping("user")
#CrossOrigin(origins="http://localhost:4200", allowedHeaders="*")
public class ProductController {
#Autowired
private IProductService productService;
#GetMapping("product/{id}")
public ResponseEntity<Product> getProductById(#PathVariable("id") Integer id) {
Product product = productService.getProductById(id);
return new ResponseEntity<Product>(product, HttpStatus.OK);
}
#GetMapping("products")
public ResponseEntity<List<Product>> getAllProducts() {
List<Product> list = productService.getAllProducts();
return new ResponseEntity<List<Product>>(list, HttpStatus.OK);
}
}
pom.xml is defined as follows.
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>com.app</groupId>
<artifactId>Assignment</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Assignment</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
</plugin>
</plugins>
</build>
As discussed in the link you have shared, you need to create a response class to be sent to the client who is calling the API.
For example, you might have a class saying ProductResponse which might look like this.
public class ProductResponse implements Serializable {
public Integer id;
public String name;
public List<Service> servicesList;
}
Now in the controller class, populate create the response as follows.
#GetMapping("product/{id}")
public ResponseEntity<ProductResponse> getProductById(#PathVariable("id") Integer id) {
Product product = productService.getProductById(id);
ProductResponse productResponse = createProductResponse(product);
return new ResponseEntity<ProductResponse>(productResponse, HttpStatus.OK);
}
ProductResponse createProductResponse(Product product) {
ProductResponse productResponse = new ProductResponse();
productResponse.id = product.id;
productResponse.name = product.name;
productResponse.serviceList = product.serviceList;
}
And yes, you need to specify the FetchType.EAGER in the entity class of Product.
#Entity
#Table(name = "products")
public class Product implements Serializable {
// ... Other parameters
#OneToMany(fetch = "FetchType.EAGER", cascade = CascadeType.ALL, mappedBy = "productId")
private List<Service> servicesList;
}
Hope that helps.
I am using Spring Data JPA:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
with Spring 4.3.7.RELEASE and Hibernate 5.2.9.Final.
When I query using findAll, the List returns contains null values.
Entity:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
#Entity
public class Etudiant implements Serializable {
/**
* Serial version UID
*/
private static final long serialVersionUID = -1982480763983112005L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idEtudiant")
private Integer idEtudiant;
#Column(name = "nomEtudiant")
private String nomEtudiant;
#Column(name = "prenomEtudiant")
private String prenomEtudiant;
#Column(name = "adresse")
private String adresse;
#Column(name = "dateNaissance")
private Date dateNaissance;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "etudiant_cours", joinColumns = #JoinColumn(name = "idEtudiant", referencedColumnName = "idEtudiant"), inverseJoinColumns =
#JoinColumn(name = "idCours", referencedColumnName = "idCours"))
private List<Cours> cours;
}
NB: Note that the problem is not from lombock, I had tested with getters and setters.
Repository:
#Repository
public interface EtudiantRepository extends JpaRepository<Etudiant, Integer> {
}
Service:
#Service
public class EtudiantServiceImpl {
#Autowired
EtudiantRepository etudiantRepository;
List<Etudiant> lst = new ArrayList<Etudiant>();
public List<Etudiant> getAllEtudiant() {
lst = this.etudiantRepository.findAll();
return lst;
}
}
In debug screenshot, it can be seen that etudiantRepository is null.
Maybe you are missing #EnableJpaRepositories annotation in your Configuration.
EtudiantServiceImpl is being instantiated using Dependency Injection or with the new keyword?
Finally I found the solution :
change spring version from 4.3.7.RELEASE to 4.3.10.RELEASE
you need to use context:component-scan annotation into xml configuration for scanning base package and repository package, you can find code below :
<jpa:repositories base-package="com.demo.test.repository" />
<context:component-scan annotation-config="true"
base-package="com.demo.test" />
and if findall() return null value that means table dose not having data, it is normal behavior.
and also check your datasource and entity manager connection
I am unable to retrieve embedded .I am using Spring boot ,spring data rest and spring JPA. I have 3 tables in data base
user
competency
user_competency (join/composite table with extra column)
User
#Entity
#Table(name = "\"user\"", schema = "public")
#JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "userId")
public class User implements java.io.Serializable {
private Long userId;
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);
#OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL}, mappedBy = "user")
public Set<UserCompetency> getUserCompetencies() {
return this.userCompetencies;
}
public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
this.userCompetencies = userCompetencies;
}
}
**Competency**
#Entity
#Table(name = "competency", schema = "public")
#JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "competencyId")
public class Competency implements java.io.Serializable {
private Long competencyId;
private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "competency_id", unique = true, nullable = false)
public Long getCompetencyId() {
return this.competencyId;
}
public void setCompetencyId(Long competencyId) {
this.competencyId = competencyId;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "competency")
public Set<UserCompetency> getUserCompetencies() {
return this.userCompetencies;
}
public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
this.userCompetencies = userCompetencies;
}
}
UserCompetency
#Entity
#Table(name = "user_competency", schema = "public")
#JsonIdentityInfo(
generator =ObjectIdGenerators.IntSequenceGenerator.class,
property = "id")
public class UserCompetency implements java.io.Serializable {
private UserCompetencyId id;
private Level level;
private User user;
private Competency competency;
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "competencyId", column = #Column(name = "competency_id", nullable = false)),
#AttributeOverride(name = "userId", column = #Column(name = "user_id", nullable = false)) })
public UserCompetencyId getId() {
return this.id;
}
public void setId(UserCompetencyId id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "level_id")
public Level getLevel() {
return this.level;
}
public void setLevel(Level level) {
this.level = level;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
public Competency getCompetency() {
return this.competency;
}
public void setCompetency(Competency competency) {
this.competency = competency;
}
}
UserCompetencyId
#Embeddable
public class UserCompetencyId implements java.io.Serializable {
private Long competencyId;
private Long userId;
public UserCompetencyId() {
}
public UserCompetencyId(Long competencyId, Long userId) {
this.competencyId = competencyId;
this.userId = userId;
}
#Column(name = "competency_id", nullable = false)
public Long getCompetencyId() {
return this.competencyId;
}
public void setCompetencyId(Long competencyId) {
this.competencyId = competencyId;
}
#Column(name = "user_id", nullable = false)
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof UserCompetencyId))
return false;
UserCompetencyId castOther = (UserCompetencyId) other;
return (this.getCompetencyId() == castOther.getCompetencyId()) && (this.getUserId() == castOther.getUserId());
}
}
UserCompetencyRepository
public interface UserCompetencyRepository extends JpaRepository<UserCompetency, UserCompetencyId> {
}
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Demo</name>
<description>Demo api </description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</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.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
and I want to perform GET using URI,it return me embedded object and cannot get real value of objects attributes
GET http://localhost:8080/userCompetencies
How Can I get attribute values of User and Competency object where userId=8 Help is required
After implementing suggested Projection Issue still not resolved and here is screen shot
One way would be to use projections like for example:
#Projection(name = "edit" , types = Employee.class)
public interface EditEmployeeProjection {
String getFirstName();
String getLastName();
Set<Project> getProjects();
}
With this the project list will be embedded in the result for http://localhost:8080/api/employee/1?projection=edit
Projections would be used automatically if you add excerptProjection to you repository like described here: How to expose a complete tree structure with Spring Data REST and HATEOAS?
See for example here: https://shinesolutions.com/2015/04/15/spring-data-rest-and-projections/
EDITED
In you case a projection would look like:
#Projection(name = "edit" , types = UserCompetency.class)
public interface UserCompetencyProjection {
User getUser();
Competency getCompetency();
}
With http://localhost:8080/userCompetencies?projection=edit you would then see wanted result.
EDITED 2
The code I used:
Competency.class
#Entity
#Table(name = "competency", schema = "public")
#JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "competencyId")
public class Competency implements java.io.Serializable {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "competency_id", unique = true, nullable = false)
private Long competencyId;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "competency")
private List<UserCompetency> userCompetencies = new ArrayList<>();
UserCompetency.class
#Entity
#Table(name = "user_competency", schema = "public")
#JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "id")
public class UserCompetency implements java.io.Serializable {
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "competencyId", column = #Column(name = "competency_id", nullable = false)),
#AttributeOverride(name = "userId", column = #Column(name = "user_id", nullable = false)) })
private UserCompetencyId id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
private User user;
#ManyToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
#JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
private Competency competency;
UserCompetencyId.class
#Embeddable
public class UserCompetencyId implements java.io.Serializable {
#Column(name = "competency_id", nullable = false)
private Long competencyId;
#Column(name = "user_id", nullable = false)
private Long userId;
UserCompetencyRepository.class
#RepositoryRestResource(excerptProjection = UserCompetencyProjection.class)
public interface UserCompetencyRepository extends JpaRepository<UserCompetency, UserCompetencyId> {
After Implementing This ,In my case its not working to show desired jason [![enter image description here][2]][2]
It worked out ,actually i was missing annotation of #RepositoryRestResource(excerptProjection = UserCompetencyProjection.class)
on UserCompetencyRepository class now the output look like this I am skipping as it is output , and putting necessary output.
I'm using Spring Boot and MySQL. I followed this link for setting everything up and I'm able to connect to MySql and read/write data. But there is an 1:n-relationship and I'm not able to save entities of the many side:
#Entity
public class OneSideOfRelationship {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long oneId;
private String someText;
#OneToMany(mappedBy="oneId")
private List<ManySideOfRelationship> manySide;
[Constructor / Getter / Setter]
}
#Entity
public class ManySideOfRelationship {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long manyId;
#ManyToOne(targetEntity=OneSideOfRelationship.class)
#JoinColumn
private long oneId;
private String someMoreText;
[Constructor / Getter / Setter]
}
#Transactional
public interface OneDao extends CrudRepository<OneSideOfRelationship, Long> {}
#Transactional
public interface ManyDao extends CrudRepository<ManySideOfRelationship, Long> {}
If I do this in my controller:
[...]
#Autowired
#private ManySideOfRelationship manyDao;
[...]
ManySideOfRelationship many = new ManySideOfRelationship();
many.setOneId(1L);
many.setSomeMoreText("Text");
manyDao.save(many);
[...]
I got:
org.springframework.orm.jpa.JpaSystemException: could not get a field value by reflection getter of com.package.database.OneSideOfRelationship.oneId; nested exception is org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.package.database.OneSideOfRelationship.oneId
Out of my application.properties:
spring.datasource.url = jdbc:mysql://myurl:myport/mydatabase
spring.datasource.username = myusername
spring.datasource.password = mypassword
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
And something out of pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
Hope somebody has an idea.
The oneId must be datatype of OneSideOfRelationship not long.
#ManyToOne(targetEntity=OneSideOfRelationship.class)
#JoinColumn
private OneSideOfRelationship oneId;