How to use #SecondaryTable with CrudRepository? - spring

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.

Related

I am using Spring boot jpa with Restful api services to insert multiple users in array or list

As I am new to Spring boot. I am not at all clear about mappings. By using #Onetomany mapping in one entity and #manytoOne mapping at other entities. Using the controller I have to write REST API functions to insert multiple users at a time inside an array or set. Can anyone please suggest some websites or provide some existing codes?
The #OneToMany and #ManyToOne mappings can be used according to your use-case, whether you need bi-directional mappping or not. For a simple example consider the following :
#Entity
#Table(name="ENTITY_A")
public class EntityA{
//...
#OneToMany(mappedBy="EntityA")
private Set<EntityB> entityBItems;
// getters and setters
}
#Entity
#Table(name="ENTITY_B")
public class EntityB{
//...
#ManyToOne
#JoinColumn(name="entityA_id", nullable=false)
private EntityA entityA;
public EntityB() {}
// getters and setters
}
What you need to look out for is the owning side of the relation indicated by the mappedBy . The owning entity can be used to persist and get the data from the database. But from the description in your question I cannot understand whether you actually need to use mappings at all as you just have to insert multiple users into a table without any relations to another entity. It will be more helpful if you could explain more about your use case and provide code samples for furthur analysis.
For details about the mappings article or article .
Official doc .
MappedBy signals hibernate that the owner of key (relationship) is on the other side.
This means that although you link 2 tables together, only 1 of those tables has a foreign key constraint to the other one.
MappedBy allows you to still link from the table not containing the constraint to the other table.
If you still want use #JoinColumn on both the Entities you can use #JsonManagedReference and #JsonBackReference from com.fasterxml.jackson
To save the multiple records at same time you can use yourRepository.saveAll(entities)

Find entity class by using its table name

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.

Fetching list of records based on list of Primary Key using Spring Data JPA

I need to fetch multiple records by querying on multiple Primary Keys. For instance, fetching multiple Employee records from Oracle DB
having fields as EmployeeId, EmployeeName based on multiple Primary key employee_id = {1,2,3} which will result in 3 Employee records, all within a single DB session.
I can do it one by one :
Optional<EmployeeBean> eb = employeeRepo.findByEmployeeId(Id);
Here employeeRepo extends CrudRepository<Employee, Long>
Is it possible to do batch wise record fetch with list of Primary Keys in Spring 5?
Use findByEmployeeIdIn(List<Long> ids). Here is a list of keywords you can use with spring data jpa.

is it possible to have conditional #Transient field?

Let's say if I have an Entity named person with lots of information including SSN. When other user query this person, I want to show a 'lite' version of person Entity. I could've done so by annotating SSN with #Transient, but that means the person himself would not get this field too. Is it possible to reuse the same Entity but return two different json to client? I'm using spring boot.
First of all #Transient just means that the value, the SSN in your case, won't be persisted to the database.
As for your problem annotations are static and cannot be applied dynamically.
You have 2 Options:
Define a new View class for your user.
Look at JacksonJsonViews

Hibernate Mysql mapping relationship

I'm not sure if this is possible to do in Spring 3 framework using hibernate and mysql but I would appreciate any help. I have two classes - Employee and Examiner. The examiner is an employee and an employee is also an examiner. At the same time each Examiner can examine one or more employees and an employee can only have one Examiner.
Basically what I want to know is if it is possible to show the inheritance between the Employee and Examiner, and at the same time map a unidirectional one to many from Examiner to Employee?
What I have so far - the Examiner table with the inheritance constraint:
CREATE TABLE `examiner` (
`employee_id` varchar(255) NOT NULL,
`employee_name` varchar(255) NOT NULL,
PRIMARY KEY (`enployee_id`),
FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`)):
The employee table:
CREATE TABLE `employee` (
`employee_id` varchar(255) NOT NULL,
`employee_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`employee_id`)):
I was thinking of a join table for showing the one to many behaviour but getting a compsite key for the table is not possible as I have a primarykeyjoin column.
I would appreciate any help in pulling this together as I have been stumped for days.
Java doesn't allow multiple inheritance, so unless you are using an interface I am not sure how you plan to make the two described classes instances of each other.
You could just make a class called EmployeeExaminer, and make it reference itself. With annotations it might look something like:
#Entity
public class EmployeeExaminer {
#ManyToOne
private EmployeeExaminer getExaminer() {/*...*/}
#OneToMany
private List<EmployeeExaminer> getEmployees() { /*...*/}
}
Documentation on the annotations can be found here.
Thanks #CodeChimp for your replies. I ended up following the first suggestion, and created a Self Reference class with the #onetomany and #manytoone annotations. The helper class for it works. I just have some problems implementing a controller and jsp page for adding the parent/child. But I will make a new question for that. Thanks again.

Resources