Trying CrudRepository - H2 - TableNotFound - spring

Below, my configs
Pom.xml
`<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>`
Controller
#RestController
public class SendSmsController {
#Autowired
private DataBaseService dataBaseService;
#Autowired
private SendSmsService sendSmsService;
#RequestMapping(value="/sendSms", method=RequestMethod.POST)
public ResponseEntity<Sms> sendSms(#RequestBody Sms sms,#RequestParam(required=false) String expirationDate) {
if(sms.getBody().length() > 160){
return new ResponseEntity<Sms>(HttpStatus.UNPROCESSABLE_ENTITY);
}
dataBaseService.saveSms(sms);
return sendSmsService.sendRequest(sms);
}
}
DataBaseService
#Data
#Service
public class DataBaseService {
#Autowired
private SmsRepository smsRepository;
public void saveSms(Sms sms) {
//I try smsRepository.save(sms) too
smsRepository.save(new Sms(sms.getTo(),sms.getTo(),sms.getBody()));
}
}
SmsRepository
public interface SmsRepository extends CrudRepository<Sms, Long> {
}
Sms Class
#Data
#Entity
#JsonIgnoreProperties(ignoreUnknown = true)
public class Sms {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#JsonProperty
private String from;
#JsonProperty
private String to;
#JsonProperty
private String body;
public Sms(String from, String to, String body){
this.from = from;
this.to = to;
this.body = body;
};
public Sms(){
}
}
Config
#Configuration
public class Config {
#Bean
public SendSmsService sendSmsService(){
return new SendSmsService();
}
#Bean
public DataBaseService dataBaseService(){
return new DataBaseService();
}
This issue occurs when the code reaches "smsRepository.save(sms)". I follow this tutorial https://spring.io/guides/gs/accessing-data-jpa/ but i think i missing configs. Thank you for any help!
The error again: org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [insert into sms (id, body, from, to) values (null, ?, ?, ?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
Caused by: org.h2.jdbc.JdbcSQLException: Table "SMS" not found; SQL statement:
insert into sms (id, body, from, to) values (null, ?, ?, ?) [42102-187]

The Problem was in my class.
After this work
public class Sms {
#Id
private String id;
#JsonProperty
#Column(name="fromNumber")
private String from;
#JsonProperty
#Column(name="toNumber")
private String to;
#JsonProperty
#Column(name="bodyMessage")
private String body;

Related

Spring boot -Axon framework NoHandlerForCommandException: No Handler for command

I am getting NoHandlerForCommandException: No Handler for command while trying to use Axon framework with Spring boot.
Below are my Java files :
The Rest controller ->
#RestController
#RequestMapping("/product")
public class ProductController {
#Autowired
private CommandGateway gateway;
#PostMapping
public ResponseEntity createProduct(#RequestBody CreateProductModel model) {
CreateProductCommand command=CreateProductCommand.builder()
.price("$123")
.productId(UUID.randomUUID().toString())
.product("Shoe")
.build();
String s=gateway.sendAndWait(command);
return new ResponseEntity<String>(HttpStatus.CREATED);
}
The ProductCreatedEvent object ->
import lombok.Data;
#Data
public class ProductCreatedEvent {
#TargetAggregateIdentifier
private String productId;
private String product;
private String price ;
}
The command class CreateProductCommand ->
#Builder
#Data
public class CreateProductCommand {
#TargetAggregateIdentifier
private final String productId;
private final String product;
private final String price ;
}
The Aggregate class ->
#Aggregate
public class ProductAggregate {
#AggregateIdentifier
private String productId;
private String product;
private String price ;
public ProductAggregate() {
}
#CommandHandler
public ProductAggregate(CreateProductCommand command) {
//TODO: Validation logic can be handled here
ProductCreatedEvent event=new ProductCreatedEvent();
BeanUtils.copyProperties(command, event);
AggregateLifecycle.apply(event);
}
#EventSourcingHandler
public void on(ProductCreatedEvent event) {
this.price=event.getPrice();
this.productId=event.getProductId();
this.product=event.getProduct();
}
}

Save creationTimestamp and updatedTime in spring + hibernate

I need to update the postgres DB with createdDate and updatedDate
I tried using approach 1, But it is inserting null values.
When I read about, it seems the #prepersist annotations does not work for session.
So I decided to go with Approach 2 : Hibernate #CreationTimeStamp Annotation, I added hibernate-annotations maven dependency, But #CreationTimeStamp is not resolved and gives compilation error.
Can someone advise me on how I can resolve the issue ?
Approach 1
Entity class annotated with #Entity and #Table
public class Status{
#Id
#Column(name = "run_id")
private int run_id;
#Column(name = "status")
private String status;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "created_date" , updatable=false)
private Date created;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updated_date" , insertable=false)
private Date updated;
#PrePersist
protected void onCreate() {
created = new Date();
}
#PreUpdate
protected void onUpdate() {
updated = new Date();
}
//Getters and setters here
}
implementation class is
sessionFactory.getCurrentSession().save(status);
Approach 2
using #CreationTimeStamp and #updatedTimeStamp. But the maven dependency
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-annotations -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.0-Final</version>
</dependency>
does not add these annotations to classpath
Is there a reason you are using the session.save() method instead of an entitymanager? I'll post an example of my application using an entitymanager to persist and merge entities. Also I am using java.time.LocalDateTime instead of java.util.Date, that's why I don't need #Temporal.
This may also help: How to use #PrePersist and #PreUpdate on Embeddable with JPA and Hibernate
If you want to use an entitymanager this will help: Guide to the Hibernate EntityManager
Entity class:
public abstract class AbstractEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(updatable = false, nullable = false)
private Long id;
#Column
private LocalDateTime createdTimestamp;
#Column
private LocalDateTime modifiedTimestamp;
#Version
private Long version;
#PrePersist
public void setCreationDateTime() {
this.createdTimestamp = LocalDateTime.now();
}
#PreUpdate
public void setChangeDateTime() {
this.modifiedTimestamp = LocalDateTime.now();
}
//Getter and setter
}
Abstract database service class:
public abstract class AbstractDatabaseService {
#PersistenceContext(name = "examplePU")
protected EntityManager entityManager;
}
Example Entity Repository Interface:
public interface ExampleRepository {
ExampleEntity save(ExampleEntity exampleEntity);
}
Example Entity Repository Implementation:
public class ExampleRepositoryImpl extends AbstractDatabaseService implements ExampleRepository , Serializable {
#Transactional
#Override
public ExampleEntity save(ExampleEntity exampleEntity) {
ExampleEntity toPersist;
// Updating an already existing entity
if (exampleEntity.getId() != null) {
toPersist = entityManager.find(ExampleEntity .class, exampleEntity.getId());
// Omitted merging toPersist with the given exampleEntity through a mapper class here
} else {
toPersist = exampleEntity;
}
try {
toPersist = entityManager.merge(toPersist);
} catch (Exception e) {
// Logging e
}
return toPersist;
}
}
Hope this helps.

Spring Data JPA Redis : Cannot write custom method based query

I have configured Spring Data JPA with Redis and using RedisRepositories with provides methods like find(), findAll() etc. All these methods seem to be working just fine, but I am not able to write my custom method like.
RedisEntity findByGenderAndGrade(String gender, String grade);
RedisEntity is a simple POJO Entity class. If you want any more info, please let me know in messages.
Following is my entity:
#Data
#RedisHash("test1")
public class RedisEntity implements Serializable {
#Id
#GeneratedValue
private String id;
private String name;
private String gender;
private Integer grade;
}
Repository:
#Repository
public interface TestRepository extends JpaRepository<RedisEntity, String> {
List<RedisEntity> findAllByGender(String gender);
List<RedisEntity> findAllByGrade(Integer grade);
}
Service/Controller:
#Override
public List<RedisEntity> getById(String id) {
return testRepository.findById(id); //returns data perfectly.
}
#Override
public List<RedisEntity> getAllByGender(String gender) {
return testRepository.findAllByGender(gender); //returns []
}
#Override
public void saveEntity(RedisEntity redisEntity) {
testRepository.save(redisEntity); // saves it in redis perfectly.
}
Also,
findByGender and findAllByGender both give [], although I can see data in my redis database and save it as well.
As requested by FrançoisDupire,
#Configuration
public class RedisConfig {
#Autowired
private DeploymentProperties deploymentProperties;
private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
#Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6379);
redisStandaloneConfiguration.setPassword(RedisPassword.of("root"));
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
#Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
Also, I had referred this article: Baeldung article on Spring data redis
As mentioned by #JoshJ and verified by myself and others,
The solution to the problem is:
Adding #Indexed annotation
to all those columns/fields which need to be used with all finds.
#Data
#RedisHash("EmployeeDetails")
public class RedisEntity {
#Id
private String employeeId;
private String firstName;
private String lastName;
#Indexed
private String gender;
#Indexed
private String grade;
}
We have the Spring Data Redis Library which provides the scope to write the custom method.Attaching Sample code.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.8.RELEASE</version>
</dependency>
Entity Definition
#Data
#RedisHash("EmployeeDetails")
public class RedisEntity {
#Id
private String employeeId;
private String firstName;
private String lastName;
private String gender;
private String grade;
}
Repository Definition
#Repository
public interface RedisEntityRepository extends CrudRepository<RedisEntity, String>{
List<RedisEntity> findAllByGenderAndGrade(String gender, String grade);
}
Implementation
#Component
public class RedisEntityImpl implements RedisEntityService {
#Autowired
private RedisEntityRepository redisEntityRepository;
#Override
public List<RedisEntity> getAllByGenderAndGrade(String gender, String grade) {
return redisEntityRepository.findAllByGenderAndGrade(gender,grade);
}
}
Properties
spring.cache.type = redis
spring.redis.host = localhost
spring.redis.port = 6379

Spring Data postgresql 10 insertion does not work

I am working on spring boot application with RestController, Service a Repository and an Entity.
My problem is when I call the web service to save my data in the data base, it seems it works fine and there is no exception thrown but when I check my data base I find that the table was created but I find no data saved. and here is what I get in the output(for each element in my list):
Hibernate:
insert
into
table_name
(columnOne, columnTwo)
values
(?, ?)
Here is my code:
RestController:
#RestController
#RequestMapping(path = "/api/")
public class myController {
#Autowired
private MyService myService;
#PostMapping(path="/inject/{year}")
public void myControllerMethod(#PathParam("year") Year year) {
this.myService.myServiceMethod(year);
}
}
Service:
#Service
public class MyService {
#Autowired
MyRepository myRepository;
public void myServiceMethod(Year year) {
List<MyEntity> myEntityList = this.parseMyEntityList(year);
this.myRepository.save(myEntityList)
}
}
Repository:
#Repository
public interface MyRepository extends CrudRepository<MyEntity, Long>, JpaSpecificationExecutor<InseeLibelle> {
}
Entity:
#Entity
#Table(name = "table_name", indexes = {
#Index(name = "columnOne_idx", columnList = "columnOne"),
#Index(name = "columneTwo_idx", columnList = "columnTwo"),
})
public class MyEntity{
#JsonIgnore
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long columnId;
#Column
private Integer columnOne;
#Column
private String columnTwo;
public Integer getColumnOne() {
return columnOne;
}
public void setColumnOne(Integer columnOne) {
this.columneOne = colmunOne;
}
public String getColumnTwo() {
return columnTwo;
}
public void setColumnTwo(String columnTwo) {
this.columnTwo = columnTwo;
}
}
I tried to add this line in the repository but it does not work too:
<S extends MyEntity> Iterable<S> save(Iterable<S> entities) ;
Perhaps the problem is with the pgAdmin (like my case), it does not show the data but they exist in the database, try findAll method in the repository or check them with select * directly.

SpringBoot with JPA in IntelliJ

I'm just starting with Spring, and actually I'm step by step tutorial so everything would work well, but somehow I've got problem with running spring boot after adding JPA elements.
Earlier I had problem with Database type NONE, so I manually added depedency:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.12.1.1</version>
<scope>runtime</scope>
</dependency>
But I feel that still something is missing in pom file which looks like this:
Pom.XML
Consol output with an error looks like this:
Console output
Implementation:
1.
class Topic
2.
class TopicController
3.
class TopicRepository
4.
class: TopicService
5.
run class
You need to annotate Topic class:
package defaultpackage.topic;
/**
* Created by zales on 02.03.2017.
*/
#Entity
public class Topic {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
private String name;
private String discription;
public Topic() {
}
public Topic(String id, String name, String discription) {
super();
this.id = id;
this.name = name;
this.discription = discription;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDiscription() {
return discription;
}
public void setDiscription(String discription) {
this.discription = discription;
}
}
You can see a similar sample with Entities and Repositories in here:
https://github.com/ccoloradoc/HibernateFilePermissionSample
Also make sure all your entities are in same package(or subpackage) as your SpringBootApplication.

Resources