Find entity class by using its table name - spring

I have the name of a table .
I want to retrieve entity class of this table in Spring JPA.
The table name may differ from its entity class name.
I searched for a lot, but the solutions were to find the table name using the entity class . That is, quite the inverse is what I need.
Do you have any suggestions for this problem?

Assuming you know how to map entity class to a table name, you can get a list of all entity classes using JPA metamodel API, and subsequently build a complete inverse mapping.

Related

Is it necessary to use Entity annotation for Select query records from Database

I have spring boot application with JPA and MySQL. The table is already created and data are present. From the spring boot application, we need to create two API - get a particular record using id and get all the records. I created a model class but confused with usage of #Entity. Because I'm not going to insert/delete a record from the database. I want to use only for select the record.
For Select query (findBy), do we need to use #Entity annotation at the top of model class?
Yes, you would need to use #Entity to mark your model class, this tells JPA that your class is used for mapping to and from a database table. If you want to make sure that you don't accidentally overwrite the data, you could implement a check via #EntityListener, as described in this answer.

Search for a String in a column of List of Strings using Spring jpa query

I have a Spring Boot application and I am using Spring Data JPA to query a PostgreSQL database.
I have a column of List type in my database. Now I need a query to search all those rows where my input parameter is present in this list.
eg. I have a column of type List containing any of these values: ["cat","dog","cow"].
I need to find all those rows where "cat" is one among the list.
Can you help me with the format of this query? Thanks in advance.
From what I could understand, you have a DB table, let's say Sample. Now this table has multiple columns with one column whose values can be either of "cat","dog","cow". Let's assume the column name to be 'sampleName'.
So, in your code you must be having an #Entity class for Sample with #Column sampleName, and a corresponding JPA repository - SampleRepository.
Now, the code for requirement should look like as shown below:
public interface SampleRepository extends JpaRepository<Sample, Long> {
Optional<Sample> findBySampleName(String sampleName);
}
In above JPA repository, I have assumed that you have an #Id field of type Long in your entity Sample. Also, I have made use of method-name strategy. Spring boot will automatically translate this method name to a SQL query at run time like - SELECT * FROM sample WHERE sampleName = 'cat'. This value cat will be provided to your repository method as an argument from #Service layer.
Hope this helps!
In addition to this, you can also choose to use the native query approach. Please refer - https://www.baeldung.com/spring-data-jpa-query for more details.

Querying multiple tables using jpa repository

Suppose if I have 3 entities - User, Skills, Department
and I have repositories corresponding to all of them - UserRepository, SkillRepository, DepartmentRepository.
I understand that the relation mapping between entities i.e. one-one many-many should be specified in the respective entity classes. The question is I want to use all of the 3 entities in a query. How would I do it? A single repository is associated with only one entity right? So, how/where would I write it?
As there are many different ways to specify queries with Spring Data JPA there are various answers to this.
Maybe you don't have to. If entity A references B and you just want to get the Bs with your A you simply use your ARepository to load As and use object navigation to get your Bs. You might read up on eager and lazy loading for more information about how to control this.
If you want referenced entities in the where condition you can use property paths in your query method names: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions
If you are using #Query annotations you can do (almost) whatever you want with JPQL. Among others, you may as well navigate properties to use them in where clauses.
In general, you'd put that query in the matching repository based on the primary entity returned.

How to use #SecondaryTable with CrudRepository?

I'm using SecondaryTable to map bean schema to multiple tables:
#Entity
#Table(name = "address1")
#SecondaryTables({
#SecondaryTable(name="address2")
})
How an I then tell spring to create a Repository that uses the values from table address2?
interface AddressRepository extends CrudRepository<Address, Long> {
//this one uses address1
}
I then want to be able to query only the secondary table by the CrudRepository. But how can I explicit tell spring to query the address2 table using the AddressRepository above?
(think of address2-table as a kind of archive table. Only if the address is not found in the primary address1-table, then address2 should be queried).
You can represent two tables which are store different but related data in one entity by using SecondaryTable like user and user_address tables. What You are trying is storing same data in two different tables whhich are identically same. Therefore, SecondaryTable doesn't fit your needs. You should use inheritance annotation with strategy table per class. Here is an example;
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AddressBase {
...
...
...
}
#Entity
#Table(name='address1')
public class Address1 extends AddressBase {}
#Entity
#Table(name='address2')
public class Address2 extends AddressBase {}
Then, you can write repository for each entity and do whatever you want.
I think you are misunderstanding what #SecondaryTable is for. It is a way to split a single entity among different database tables.
From the docs (http://docs.oracle.com/javaee/7/api/javax/persistence/SecondaryTable.html)
Specifies a secondary table for the annotated entity class. Specifying
one or more secondary tables indicates that the data for the entity
class is stored across multiple tables. If no SecondaryTable
annotation is specified, it is assumed that all persistent fields or
properties of the entity are mapped to the primary table. If no
primary key join columns are specified, the join columns are assumed
to reference the primary key columns of the primary table, and have
the same names and types as the referenced primary key columns of the
primary table.
Your annotations, in their current state, say that there exists an Address entity, with data in the address1 and address2 table, which can be combined by joining on the primary key of the address1 table.
I think for what you want to do, and have it work without overriding your CrudRepository, is to just use different tables. You will need to query both tables anyway if I am understanding you correctly.

Assigning values to unmapped property

Suppose, I have a Customer class with some properties like
name,
id,
object of CompetentAuthority class etc.
name,id etc is mapped in .hbm file but i have taken icollection of CompetentAuthority object and I didnt do any entery in .hbm file for CompetentAuthority(one-to-many).
In CompetentAuthority class i have taken Customer object and in .hbm file of CompetentAuthority i did many-to-one relationship.
Nnow,i want list of customers with it's CompetentAuthority list but as its just an object and no mapping is done,criteria API doesn't allow me to do innerjoin;it gives me error like "cannot resolve property"
Is there any way to achieve this.
If you are wanting to use the Criteria API to apply an INNER JOIN, then no you cannot do that. The CompetentAuthority object needs to be mapped with NHibernate and the Customer object's mapping file will need to be modified to establish the relationship between the two entities.
If for some reason you are not able to map the CompetentAuthority, you could take advantage of mixing the ISession.CreateSQLQuery() method and the Transformers.AliasToBean() method which will allow you to hydrate an unmapped entity.
For more information on this technique, please refer to the Official NHibernate documentation section titled "Returning non-managed entities" or search around for using the AliasToBean() method: http://nhibernate.info/doc/nh/en/index.html#d0e11066

Resources