Use #Query annotation not in the JpaRepository - java

I have the User entity in the database and it's JPA entity. I also have the UserDescription class which hasn't table in the database. I want to instantiate UserDescription class using different tables and entities. But I don't want to use EntityManager for it. So I found SELECT new ... pattern which can be used in #Query annotation, it's the perfect solution.
But I have simple issue - I need to annotate some method declaration which should be in interface. Usually it's done in JpaRepository, but UserDescription - isn't entity, so I can't do this!
Also, I tried to create POJO interface(UserDescriptionService) with method declaration which annotated using #Query annotation, tried to create field with this interface in the controller(), and annotated it with Autowired and of course got:
Field userDescriptionService in UserController required a bean of type
'UserDescriptionService' that could not be found.
So, how can I use #Query annotation not in the JpaRepository or how can I get JpaRepository for the non-entity class?

As M. Deinum already mentioned. You are not forced to return only Entities in JpaRepositories.
You can use the Constructor Expression (aka select new) or also projections.
Find more about projections here:
https://docs.spring.io/spring-data/jpa/docs/2.0.9.RELEASE/reference/html/#projections

Related

Hibernate Bytecode Instrumentation: Set fetched property values to their fields right away

I'm working on an enterprise application that uses Hibernate and EJB, and I'm utilizing Hibernate's Bytecode instrumentation to implement true lazy-loading of properties having bidirectional #OneToOne associations. I have a service method implemented using EJB, and as we all know, EJB uses RMI, which uses native Java serialization and deserialization to facilitate RPC invocations. The service method returns an entity with needed properties already fetched using JPQL, but since Hibernate doesn't set the fetched properties eagerly to their target fields, clients calling the service method end up receiving entities with properties having null values. Aside from calling the property getters manually before returning the entity, is there a way to tell Hibernate to set fetched property values automatically to their corresponding fields?
I'm using Hibernate 5.3.15 and JBoss EAP 7.2.8.
First of all, EJB doesn't necessarily use RMI, I guess what you mean is EJB remoting. There is no way that I know of to force field initialization except for initializing the fields through some means (access). One way to overcome this is to use DTOs that simply do not do any lazy initialization.
I think that this might be a bug in the serialization code of Hibernate for such bytecode enhanced proxies, so please create an issue in the issue tracker(https://hibernate.atlassian.net) with a test case(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) that reproduces the issue.
If you want to take the DTO approach, I think this is a perfect use case for Blaze-Persistence Entity Views.
I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.
A DTO model for your use case could look like the following with Blaze-Persistence Entity-Views:
#EntityView(User.class)
public interface UserDto {
#IdMapping
Long getId();
String getName();
UserDetailsDto getDetails();
#EntityView(UserDetails.class)
interface UserDetailsDto {
#IdMapping
Long getId();
String getFirstname();
}
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
UserDto a = entityViewManager.find(entityManager, UserDto.class, id);
The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
Page<UserDto> findAll(Pageable pageable);
The best part is, it will only fetch the state that is actually necessary!

How does CrudRepository know which table to get data?

I built an application with Angular, SpringBoot and MySQL Database.
It uses CrudRepository and I don't understand it (everything is working OK).
How does the controllers/repository know which table to get the data from? I mean, I don't specify table name.
Can someone explain me how this works?
When you extend CrudRepository you define its generic type. In Here you tell from which Entity class the repository will fetch the data. And Entity classes in JPA are used to represents Tables. So thats how it knows from where to get data. for example :
public interface UserRepository extends CrudRepository<User, Long> {
}
In the code above, I specified the generic type to be User, Also User is my Entity class which represents users table in my database. So this Repository will deal with users table.
In spring boot data JPA application any model is annotated with either #Entity or along with #Table(name = "User"). In case of former, the default table name is same as Entity Name.
Also, when you create any repository like:
public interface UserRepository extends CrudRepository<User, Long> the default implementation of Entity i.e User is referred to perform all operations in generic manner.
I found the following explanation helpful since it goes through all possible combinations of #Entity and #Table and lists the corresponding query.
https://walkingtechie.blogspot.com/2019/06/difference-between-entity-and-table.html

How to instantiate a class from string FQN in database in hibernate?

I'm trying to convert a legacy application to hibernate.
I have an entity that has a field, which should be instantiated to object instance based on a fully qualified name string in a database.
Consider the example below - if I have somePackageName.FirstClass in a database the someObject field should be an instance of FirstClass.
I guess I could use property access and persist / retrieve a string but that doesn't look very elegant to me.
I cannot use #PostLoad etc. - I'm using pure hibernate with spring (not JPA) - these annotations get ignored.
I know for example in MyBatis one can register a custom handler for field. Would anything similar be available in Hibernate?
I'm new to hibernate so I'm not really sure what the options are.
#Entity
class SomePersistentClass{
private SomeInterface someObject;
}
class FirstClass implements SomeInterface{
}
class SecondClass implements SomeInterface{
}
You can use JPA features such as #PostLoad, etc callbacks simply by enabling the proper Hibernate event listeners. Check the Hibernate EntityManager guide for details.
But this one is even easier. This is the role of a Type in Hibernate. First, you'll have to write an implementation of org.hibernate.type.Type or org.hibernate.usertype.UserType and specify that in #Type( type=... ) that handles the conversions (lots of web resources about writing custom Hibernate types). Then annotate your 'someObject' attribute with #Type( type="your.custom.TypeImpl" )

Hibernate - how to load into POJO which is not an entity

I have an entity named father and son1 and son2 who are mapped as collections inside father
Lets say father has a,b,c properties son1 has a,d and son 2 has b,e
and I have a bean which contains a,b,d,e called MyBean in one query.
Can I use it in a simple query using addEntity(MyBean.class) where my MyBean is not an hibernate entity (POJO)?
the POJO is as simple as it gets without annotations
class POJO {
Object a,b,d,e;
//get and set's and empty c'tor etc
}
use the new keyword and create the object in your search query
this only works for jpql
Can I use it in a simple query using addEntity(MyBean.class) where my MyBean is not an hibernate entity (POJO)?
I don't believe so. I believe that hibernate must know about all classes it persists via mappings.

Is is possible to create a custom jpa annotation in java

Jpa one of the big successfull module of jpa and so are its annotation features .I have weird requirement in which i need to create jpa annotation ,one that jpa can process
ex. We have in jpa a table annotation that create a table for this java pojo class.
i need to make another annotation that behaves exactly as what table annotation does + some of my custom reqirements;
what is mean
if i create a customAnnotation like #Anil that is suppose to work same as #Table Annotation does
than
#Anil
public class Anp
{
}
than this should create a table in the database is that possible or not .if it is give me some way to do this
thanks
JPA does not process just any annotation. The JPA implementation processes the annotations that it supports and these are typically just the javax.persistence annotations, and optionally its own extensions. Your JPA provider may allow you to define your own, but this is not going to be very common - look at the docs for your JPA provider if they allow a user to define annotations.
For example, the JPA provider I have used (DataNucleus JPA) allows the user to provide annotations for the class or for the field/property.

Categories

Resources