I am trying to create a restful application by following a You tube video as I am completely new to this. I am unable to create table automatically using hibernate.ddl-auto = update. I also tried using hibernate.ddl-auto = create and spring.jpa.hibernate.hbm2ddl.auto = create. I also have to change the server port every single time to run the application. How to fix the issues?
RestfulApplication1.java
package com.springboot.first.app;
import org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication
#EnableAutoConfiguration(exclude=
{DataSourceAutoConfiguration.class})
public class RestfulApplication1 {
public static void main(String[] args) {
SpringApplication.run(RestfulApplication1Application.class, args);
}
}
application.properties
spring.datasource.username=root
spring.datasource.password=**********
spring.datasource.url=jdbc:mysql://localhost:3306/emp?useSSL=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.datasource.driver.class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
server.port = 6104
Employee.java
package com.springboot.first.app.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
#Data
#Entity
#Table(name="Employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "first_name" , nullable = false)
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name="email")
private String email;
}
Console output
Use this config:
spring.jpa.hibernate.ddl-auto=update
Related
I have a entity
#AllArgsConstructor
#NoArgsConstructor
#Setter
#Getter
#Entity
#Table(name = "t_org")
public class Organization {
/**
* id of the organization.
*/
#Id
#GeneratedValue(generator = "UUID")
#Column(name = "c_id", columnDefinition = "BINARY(16) DEFAULT (UUID_TO_BIN(UUID(), TRUE))")
private UUID id;
/**
* legal name of the organization.
*/
#Column(name = "c_legal_name", nullable = false, unique = true)
private String legalName;
/**
* alias name of the organization.
*/
#Column(name = "c_alias", nullable = false, unique = true)
private String alias;
/**
* timestamp when the organization was created.
*/
#Column(name = "c_date", insertable = false, updatable = false,
columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",
nullable = false)
private Instant ts;
}
now when I am saving this entity from service and when I want to access timestamp by calling saveAndFlush(orgObject).getTs();
Timestamp is always null but I can see it is getting saved in database but jpa not returning it.
I tried annotating it with #CreationTimestamp but that will set jvm's timestamp and I want db's timestamp.
I tried like this and this is fetching the timestamp. I created an entity class called post. and made API controller and service class for that. Here is the whole code.
Post entity class
package com.project.demo.entity;
import java.time.Instant;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
#Entity
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "post")
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String thePost;
private Instant creationTime;
}
service class
package com.project.demo.service;
import java.time.Instant;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.project.demo.entity.Post;
import com.project.demo.repository.PostRepository;
import jakarta.transaction.Transactional;
#Service
public class PostService {
#Autowired
private PostRepository postRepository;
#Transactional
public List<Post> getPosts(){
return postRepository.findAll();
}
#Transactional
public void savePost(Post post) {
post.setCreationTime(Instant.now());
postRepository.save(post);
}
}
controller class for rest API
package com.project.demo.controller;
import java.util.List;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.project.demo.entity.Post;
import com.project.demo.service.PostService;
#RestController
#RequestMapping
public class Controller {
#Autowired
private PostService postService;
#GetMapping("/posts")
public List<Post> getPost() {
return postService.getPosts();
}
#PostMapping("/posts")
public String savePost(#RequestBody Post post) {
post.setId(0);
postService.savePost(post);
return "Post saved";
}
}
application.property
spring.datasource.name=test
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:postgresql://localhost:5432/stackoverflow
spring.datasource.username=postgres
spring.datasource.password=123
spring.jpa.show-sql=true
The screenshots of fetched data in postman
The screenshot
Hope this helps.
I am trying to fetch all the records using JPA findAll. If I run the same query in the terminal, I get some rows as a result, but not through JPA. I tried other answers on stackoverflow, but nothing worked. I tried adding public getters and setters, although which I assume was done by the annotations.
Model class:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
#Entity
#Table(name = "tea")
public class Product {
#Id
#GeneratedValue(generator = "prod_seq", strategy = GenerationType.SEQUENCE)
#SequenceGenerator(name = "prod_seq", sequenceName = "seq_prod", allocationSize = 1, initialValue = 1)
#Column(name = "product_id")
private int productId;
private String name;
#Column(name = "price_per_kg")
private int pricePerKg;
private String type;
#Lob
#Column(length = 2000)
private String description;
#Column(name = "image_url")
private String imageUrl;
private String category;
}
Service class:
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tea.exceptions.ProductNotFoundException;
import com.tea.models.Product;
import com.tea.repository.ProductRepository;
#Service
public class ProductServiceImpl implements ProductService{
#Autowired
ProductRepository productRepository;
#Override
public List<Product> getAll() throws ProductNotFoundException {
return productRepository.findAll();
}
}
Edit: Adding the repository code:
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.tea.models.Product;
public interface ProductRepository extends JpaRepository<Product,Integer >{
#Query("from Product where type like :type ")
List<Product> findByType( String type);
#Query("from Product where type =?2 and category= ?1")
List<Product> findByCategoryAndType(String category, String type);
#Query("from Product where category like :category")
List<Product> findByCategory(String category);
}
I think query should contain alias name for table like Product p and then condition like p.type.
There is an reccuring issue with my Spring Boot application (using Oracle Java 8, Hibernate and Oracle DB).
I have following error in the logs:
WARN o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions - SQL Error: 1, SQLState: 23000
ERROR o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions - ORA-00001: unique constraint (MY_SCHEMA.SYS_C0057302) violated
This constraint (SYS_C0057302) is UUID being UNIQUE. (UUID VARCHAR2(32) NOT NULL UNIQUE)
I cannot provoke this behaviour running it locally (even with load tests) - locally on windows it looks fine, but on RHEL (where it is deployed) problem occurs all the time.
Note that I have dozen more entity classes which all have UUIDs, but only this class is generating such strange duplicates all the time.
No idea how to fix it. Cannot find root cause of this.
Examples of UUIDsand classes used below:
There is a bit of normal UUIDs at the start, but after some time strange and duplicated UUIDs are being created. On 2 different RHEL envs.
Examples of normal UUIDs:
0C34561DD75D422CAD652715DF6C6E75
0CB86A03945040B9886752CC07EB116E
0DAA1A3AF2B5438F8CB9489348A92223
0EAE079E621B4D2B8E8BE445F76B14C9
0FCF05797E7E40DE8D3A9D6A3B44AAE1
12DEBCAB53C94285A4C3FF32C5A0BF8E
132A877F404D44069F78D9B74DD4BDC9
1338A8CE09B14552B78CBAD640A3CF29
136310C44374412FB5B1B8FAF7E35330
Example of strange UUIDs generated by UUID.randomUUID() - 99% of UUIDs are like that, very similiar, with 3 as number that comes up a lot:
33333330333433363333333233333339
33333330333433363333333333333336
33333330333433363333333433333330
33333330333433363333333433333332
33333330333433363333333433333333
33333330333433363333333533333330
33333330333433363333333533333333
33333330333433363333333533333339
33333330333433363333333533343332
33333330333433363333333633333332
33333330333433363333333633333334
33333330333433363333333733333333
33333330333433363333333733343335
33333330333433363333333833333333
33333330333433363333333933333332
TaskEntity class:
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import ----DashboardTaskDto;
import ----SimpleUserDto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name = "TASK")
#ToString
#EntityListeners(AuditingEntityListener.class)
#Slf4j
class TaskEntity {
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TASK_SEQ")
#SequenceGenerator(sequenceName = "TASK_SEQ", allocationSize = 1, name = "TASK_SEQ")
#Id
private Long id;
#Column(name = "KKF")
private String kkf;
#EqualsAndHashCode.Include
private UUID uuid = UUID.randomUUID();
private String customerName;
private String assignedUserName;
private String assignedUserRole;
private int dpd;
private Boolean bgk;
private String courtProceedings;
private String name;
private LocalDateTime dueDate;
private LocalDateTime doneDate;
private BigDecimal totalLiabilities;
private Long issueActivityId;
private String userId;
#Enumerated(EnumType.STRING)
private TaskStatus status;
#CreatedDate
private LocalDateTime created;
#LastModifiedDate
private LocalDateTime modified;
#Builder
public TaskEntity(String kkf, String customerName, String assignedUserName, String assignedUserRole, int dpd, Boolean bgk, String courtProceedings, String name, LocalDateTime dueDate, LocalDateTime doneDate, BigDecimal totalLiabilities, Long issueActivityId, String userId, TaskStatus status, LocalDateTime created, LocalDateTime modified) {
this.kkf = kkf;
this.customerName = customerName;
this.assignedUserName = assignedUserName;
this.assignedUserRole = assignedUserRole;
this.dpd = dpd;
this.bgk = bgk;
this.courtProceedings = courtProceedings;
this.name = name;
this.dueDate = dueDate;
this.doneDate = doneDate;
this.totalLiabilities = totalLiabilities;
this.issueActivityId = issueActivityId;
this.userId = userId;
this.status = status;
this.created = created;
this.modified = modified;
}
Task repository class:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.Repository;
import org.springframework.lang.Nullable;
import java.util.Optional;
interface TaskRepository extends Repository<TaskEntity, Long> {
TaskEntity save(TaskEntity from);
Optional<TaskEntity> findByIssueActivityId(Long id);
Page<TaskEntity> findAll(#Nullable Specification<TaskEntity> spec, Pageable pageable);
}
TaskCreator used for entity creation/updates:
class TaskCreator {
public TaskEntity from(IssueActivityEntity issueActivityEntity) {
IssueEntity issue = issueActivityEntity.getIssue();
CustomerEntity customer = issue.getCustomer();
UserEntity user = issueActivityEntity.getUser();
return TaskEntity.builder()
.kkf(customer.getKkf())
.customerName(customer.getCompanyName())
.assignedUserName(user.getName())
.assignedUserRole(user.getRole())
.dpd(issue.retrieveMaxDpd())
.bgk(customer.isBgk())
.courtProceedings(customer.getCourtProceedings())
.name(issueActivityEntity.getActivity().getStatus())
.dueDate(issueActivityEntity.getDueDate())
.doneDate(issueActivityEntity.getDoneDate())
.totalLiabilities(customer.getTotalLiabilities())
.issueActivityId(issueActivityEntity.getId())
.status(issueActivityEntity.getStatus())
.userId(user.getId())
.build();
}
TaskEntity updateFrom(final TaskEntity task, final IssueActivityEntity ia) {
IssueEntity issue = ia.getIssue();
CustomerEntity customer = issue.getCustomer();
UserEntity user = ia.getUser();
task.setKkf(customer.getKkf());
task.setCustomerName(customer.getCompanyName());
task.setAssignedUserRole(user.getRole());
task.setDpd(issue.retrieveMaxDpd());
task.setBgk(customer.isBgk());
task.setCourtProceedings(customer.getCourtProceedings());
task.setName(ia.getActivity().getStatus());
task.setDueDate(ia.getDueDate());
task.setDoneDate(ia.getDoneDate());
task.setTotalLiabilities(customer.getTotalLiabilities());
task.setIssueActivityId(ia.getId());
task.setStatus(ia.getStatus());
task.setUserId(user.getId());
return task;
}
}
Update 1:
I tried setting -Djava.security.egd=file:/dev/./urandom but this did not help at all.
I have a bord class and a bordrow class, meaning a bord has multiple bordrows in a one to many relation. Whenever I do a GET request on /bords I just want every bord model without the datetimes and without the rows, this is why I added lazy fetch and #JsonIgnore. However all attributes are sent on the request. What did I do wrong?
Bord.java:
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
#Table(name = "bords")
#Entity
public class Bord
{
#Id
#GeneratedValue
private int id;
#NotNull
private String name;
private String icon;
private String background;
#DateTimeFormat
#JsonIgnore
private Date created_at;
#DateTimeFormat
#JsonIgnore
private Date updated_at;
#DateTimeFormat
#JsonIgnore
private Date deleted_at;
#OneToMany(mappedBy = "bord", fetch = FetchType.LAZY)
private List<BordRow> bordRows;
public Bord() {
bordRows = new ArrayList<>();
}
}
BordRow.java:
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "bord_rows")
public class BordRow
{
#Id
#GeneratedValue
private int id;
#NotNull
private String title;
#ManyToOne
#JoinColumn(name="bord_id", nullable=false)
#JsonIgnore
private Bord bord;
}
BordController.java:
import com.jordibenck.scrumbords.scrumbords.entity.Bord;
import com.jordibenck.scrumbords.scrumbords.entity.User;
import com.jordibenck.scrumbords.scrumbords.repository.BordRepository;
import com.jordibenck.scrumbords.scrumbords.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(path = "/bords")
public class BordController
{
#Autowired
private BordRepository repository;
#GetMapping
public Iterable<Bord> findAll() {
return repository.findAll();
}
}
You should use the annotations in your getters. and not your private fields
Hope it helps
You should delete #DateTimeFormat.
#DateTimeFormat has conflict with #JsonIgnore.
I am trying to use the "out of the box" goodies of JPA and get data from DB to an object. It is working perfect when the JpaRepository is using a simple class as key, but for test cases when the key class is a bit complex, the jpa validation fails even for the simplest queries.
using a native_query=true will solve the issue, however I am not sure what I am doing wrong and what am I missing.
MyTestPK.java:
package com.mytest.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Embeddable;
import java.io.Serializable;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Embeddable
public class MyTestPK implements Serializable {
private String type;
private String name;
}
MyTest.java:
package com.mytest.model;
import lombok.Data;
import javax.persistence.*;
#Entity
#Table(name = "my_test")
#Data
#IdClass(MyTestPK.class)
public class MyTest {
#Id
#Column(name = "my_test_type", nullable = false)
private String type;
#Id
#Column(name = "my_test_name", nullable = false)
private String name;
#Column(name = "my_test_misc")
private String misc;
}
MyTestRepository.java:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
#Repository
public interface MyTestRepository extends JpaRepository<MyTest, MyTestPK> {
#Query(value="SELECT m FROM MyTest m")
List<MyTest> getAllObjs();
}
Getting the following error:
....
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List
com.mytest.dao.MyTestRepository.getAllObjs()!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
You can use #EmbeddedId and no need to define columns in the entity classes again.
MyTestPK.java:
package com.mytest.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Embeddable;
import java.io.Serializable;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Embeddable
public class MyTestPK implements Serializable {
#Column(name = "my_test_type", nullable = false)
private String type;
#Column(name = "my_test_name", nullable = false)
private String name;
}
MyTest.java:
package com.mytest.model;
import lombok.Data;
import javax.persistence.*;
#Entity
#Table(name = "my_test")
#Data
public class MyTest {
#EmbeddedId
private MyTestPK pk;
#Column(name = "my_test_misc")
private String misc;
}