I am trying to implement something for converting between my Entities and DTO.
I have base class for my DTOs (called Models):
public class BaseModel<Entity> implements Model<Entity> {
#Override
public Entity toEntity(Class<Entity> entityClass) {
Entity entityInstance = BeanUtils.instantiate(entityClass);
BeanUtils.copyProperties(this, entityInstance);
return entityInstance;
}
}
But following test doesn't passes:
public class BaseModelTest {
#Entity
public class SomeEntity {
#Id
private Long id;
private String name;
public SomeEntity() {
}
public SomeEntity(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
#Test
public void toEntity_givenEntityClass_shouldCreateNewInstance() throws Exception {
//given
BaseModel<SomeEntity> model = new BaseModel();
//when
SomeEntity entity = model.toEntity(SomeEntity.class);
//then
assertNotNull(entity);
}
}
I got exception: (despite the fact, under debugger I see all ctors):
org.springframework.beans.BeanInstantiationException: Failed to instantiate [package.BaseModelTest$SomeEntity]: Is it an abstract class?; nested exception is java.lang.InstantiationException: package.BaseModelTest$SomeEntity
Caused by: java.lang.InstantiationException: package.BaseModelTest$SomeEntity
Caused by: java.lang.NoSuchMethodException: package.BaseModelTest$SomeEntity.<init>()
Currently to create a new SomeEntity instance you need an instance of the enclosing BaseModelTest class. SomeEntity should be an inner static class. Replace:
public class SomeEntity {
with
public static class SomeEntity {
BTW. There is no point in having a DTO class if it maps 1-1 to a model class, it does not add any value, it is only boilerplate code.
Related
I am creating first-time spring rest services with Spring Data JPA.
and getting below error.
APPLICATION FAILED TO START
Description:
Field product_repo in com.example.demo.controller.AddProduct required a bean of type 'com.example.demo.repository.ProductRepositroy' 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 'com.example.demo.repository.ProductRepositroy' in your configuration.
My class and interfaces are :
Controller
#RestController
public class AddProduct {
#Autowired
private ProductRepositroy product_repo;
#GetMapping("/add")
public String addproduct() {
Product p1 = new Product();
p1.setId(1);
p1.setName("Amit");
Product p2 = new Product();
p1.setId(2);
p1.setName("Sumit");
product_repo.save(p1);
product_repo.save(p2);
return "added successfully the recod";
}
}
Entity
#Entity
public class Product {
#Id
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Repository
public interface ProductRepositroy extends CrudRepository<Product, Integer> {
}
Application Test
#SpringBootApplication
public class Demo1Application {
public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args);
}
}
Add #Repository annotation on ProductRepositroy interface. Also instead of extending CrudRepository extend JpaRepository.
You should use #Repository in the repository to register this class in the bean.
Code should be something like this.
#Repository
public interface ProductRepositroy extends CrudRepository<Product, Integer> {
}
happy coding! :)
New to java and spring. Tried creating an app but was unsuccessful.I have the following entity and controller in my app. But at runtime i get an error. I posted snippets for easier reading.
staff.java
#Data
#Entity
public class Staff {
private int staff_id;
private String staff_name;
private String staff_email;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "staff")
private List<VisitRequest> visitRequest;
public String getStaff_name(){
return staff_name;
}
public void setStaff_name(String staff_name){
this.staff_name = staff_name;
}
public String getStaff_email(){
return staff_email;
}
public void setStaff_email(String staff_email){
this.staff_email = staff_email;
}
public int getStaff_id(){
return staff_id;
}
public void setStaff_id(int staff_id){
this.staff_id = staff_id;
}
}
StaffController.java
#Controller
#RestController
#RequestMapping("/staff/")
public class StaffController{
#Autowired
protected StaffRepository staffRepository;
#GetMapping("/Staff")
public List<Staff> getAllStaff() {
return staffRepository.findAll();
}
#GetMapping("/staff/{Staff_id}")
public ResponseEntity<Staff> getStaffById(#PathVariable(value = "Staff_id") Long Staff_id)
throws ResourceNotFoundException{
Staff staff = staffRepository.findById(Staff_id)
.orElseThrow(() -> new ResourceNotFoundException("Employee not Found"));
return ResponseEntity.ok().body(staff);
And the error that is thrown at runtime is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfigura
tion.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: No identifier specified for entity: com.Vportal.data.model.Staff
Please advice on what to do.
Your Staff entity lacks a member with an #Id annotation. This could be added to staff_id like follows:
#Data
#Entity
public class Staff {
#Id
private int staff_id;
....
}
I have an Entity that would like to extend it by adding some fields. first of all they are not accessible to me to change directly, they are in their own jar file. here are the base entities:
#Entity
table(name="ACCOUNTDEF")
public class EtAccountDef
{
private String cNumber;
private List<EtAccount> accounts = new ArrayList();
public String getCNumber()
{
return cNumber;
}
public void setCNumber(String cNumber) {
this.cNumber = cNumber;
}
#OneToMany(fetch=FetchType.LAZY, cascade={javax.persistence.CascadeType.ALL}, mappedBy="accountDef")
public List<EtAccount> getAccounts() {
return accounts;
}
public void setAccounts(List<EtAccount> accounts) {
this.accounts = accounts;
}
}
which is the parent class and the below is child class:
#Entity
#Table(name="ACCOUNT")
public class EtAccount
{
private Double accountAmount;
private EtAccountDef accountDef;
private List<EtAccountItems> accountItems = new ArrayList();
#ManyToOne(fetch=FetchType.LAZY)
public EtAccountDef getAccountDef() {
return accountDef;
}
public void setAccountDef(EtAccountDef accountDef) {
this.accountDef = accountDef;
}
#OneToMany(fetch=FetchType.LAZY, cascade={javax.persistence.CascadeType.ALL}, mappedBy="account")
public List<EtAccountItems> getAccountItems() {
return accountItems;
}
public void setAccountItems(List<EtAccountItems> accountItems) {
this.accountItems = accountItems;
}
}
so I tried these changes to achieve my goal.
#MappedSuperclass
public abstract class OtAbstractAccount extends EtAccount {
private Double AccountCommission;
#Column(columnDefinition="decimal(15,2)")
public Double getAccountCommission() {
return accountCommission;
}
public void setAccountCommission(Double accountCommission) {
this.accountCommission = accountCommission;
}
and then extend it by this entity:
#Entity
#Table(name="ACCOUNT")
public class OtCostumAccount extends OtAbstractAccount {
}
The fields are now added to the base table(EtAccount) but
after compiling I get an error in the Weblogic that says:
Caused by: org.hibernate.AnnotationException: #OneToOne or #ManyToOne
on EtAccount.accountDef references an unknown entity: EtAccountDef
I have entered these two line in my ORM file:
<mapped-superclass class="package.OtAbstractAccount" />
<entity class="package.OtCostumAccount" />
Surprisingly when i comment
<mapped-superclass class="package.OtAbstractAccount" />
from ORM the weblogic does not rise any error but when I try to load object another error will be created that say:
Caused by: javax.persistence.PersistenceException:
org.hibernate.exception.SQLGrammarException: ORA-00904:
"OtCostumAccount "."DTYPE": invalid identifier
I'm confused whit these error and I'll appreciate any help.
If you can not modify the parent class, then the default hibernate inheritance strategy apply: one table per class. This strategy require a discriminant column which, by default, is DTYPE. Did you try to add a discriminator column to your OtCostumAccount entity or create the DTYPE column ?
Here is my project structure:
An #MappedSuperclass base class:
#MappedSuperclass
public class BaseClass {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private long id;
//getter and setter
}
An #Entity extending the base class:
#Entity
public class Person extends BaseClass {
private String regisNumber;
private String name;
private int hPerWeek;
/**
* #param regisNumber
* #param name
* #param hPerWeek
*/
public Person(String regisNumber, String name, int hPerWeek) {
super();
this.regisNumber = regisNumber;
this.name = name;
this.hPerWeek = hPerWeek;
}
//getters and setters
}
The generic DAO:
#Repository
public interface IDao<T extends BaseClass> extends JpaRepository<T, Long> {
}
In my tests, creating a Person works fine:
#Autowired
IDao<Person> dao;
#Test
public void whenPersonEntityIsCreated_thenNoExceptions() {
Person person = new Person("mkd90ii", "manu", 24);
dao.save(person);
}
Nevertheless trying getting a Person :
#Test
public void whenPersonEntityIsUpdated_thenNoExceptions() {
Person person = dao.getOne(Long.valueOf(32768));
System.out.println(person.toString());
//Updating person...
}
generates me this error:
org.springframework.dao.InvalidDataAccessApiUsageException: Unknown entity: com.bockmoi.entities.BaseClass;
nested exception is java.lang.IllegalArgumentException: Unknown entity: com.bockmoi.entities.BaseClass
I do understand that's because BaseClass is not a javax.persistence.Entity, but why the creation works and not the reading?
Can someone explain me why this happens and how to overcome this?
It's a kind of dead end for me.
Thanks
I am trying to cache the data using #Cacheable for a method which don’t have parameters/arguments.
Following is my repository code:
public interface FooRepository extends JpaRepository<Foo, Integer>{
#Cacheable(value = "fooTypes",key = "#root.target.getType().getName()")
List<Foo> findAll();
}
and the Foo entity
#Entity
#Table(name = "table_name”)
public class Foo implements Serializable
{
private int id;
private FooType type;
public FooType getType(){
return this.type;
}
}
#Entity
Public class FooType {
private String name;
publc String getName(){
return this.name;
}
}
Now when I try to call the findAll() method, following exception is thrown:
Uncaught runtime error: org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 13): Method call: Method getType () cannot be found on com.sun.proxy.$Proxy162 type
Can someone advice how to configure my cache using FooType field name as key?