named native query and mapping columns to field of entity that doesn't exist in table - jpa

I have a named native query and I am trying to map it to the return results of the named native query. There is a field that I want to add to my entity that doesn't exist in the table, but it will exist in the return result of the query. I guess this would be the same with a stored proc...
How do you map the return results of a stored proc in JPA?...
How do you even call a stored proc?
here is an example query of what I would like to do...
select d.list_id as LIST_ID, 0 as Parent_ID, d.description from EPCD13.distribution_list d
The Result will be mapped to this entity...
public class DistributionList implements Serializable {
#Id
#Column(name="LIST_ID")
private long listId;
private String description;
private String owner;
private String flag;
#Column(name="PARENT_ID", nullable = true)
private long parentID;
}
parent ID is not in any table in my database. I will also need to use this entity again for other calls, that have nothing to do with this call, and that will not need this parent_id? Is there anything in the JPA standard that will help me out?

If results from database are not required for further manipulation, just for preview, you can consider using database view or result classes constructor expression.
If entities retrieved from database are required for further manipulation, you can make use of multiple select expression and transient fields.
Replace #Column annotation with #Transient annotation over parentID.
After retrieving multiple columns from database, iterate over results and manually set parentID.

Related

Spring Data JPA Select Distinct dynamic columns based on list of string input

I want to select columns based on my input (List < String >)
#Entity
#Table
public class Product {
#Id
private Long id;
private String name;
private String price;
}
I understand that to select distinct specific columns, I can use #Query("SELECT DISTINCT name FROM TABLE")
However, I want to give users the flexibility to select the columns they want. e.g. List < String > columns = Arrays.asList(["name", "price"]). This will then select distinct from both name and price columns.
For this create a custom method implementation and use one of the following (or of the many variants thereof)
construct a SQL or JPQL query using String concatenation (be careful not to introduce SQL injection vulnerabilities).
use some kind of criteria API like
JPA Criteria API
Querydsl
JOOQ

How to get db column value from Mybatis for sharding?

I use Mybatis to access db, and some tables is sharding by id with hash algorithm.
I want to write a Mybatis intecepter to change table name automatic, it need to get the sharding column value.
Table Entity:
#Data
#TableName("m_user")
public class User {
#TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Integer age;
}
UserMapper sql:
#Select("select * from m_user where id = #{id2} and name = #{name2};")
List<User> selectByIdAndName(Integer id2, String name2);
I use boundSql.getParameterObject() and boundSql.getParameterMappings() to check, but I can not make sure whether the sharding column id is in sql and then get the value of the sharding column.
ParameterMappings values and ParameterObject values are here:
parameter mapping:ParameterMapping{property='id2', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}
parameter mapping:ParameterMapping{property='name2', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}
params:{id2=1, param1=1, name2=name1, param2=name1}
The parameters are Mapper function parameters, but I need sharding column id and value, program can only get id2 or param1.
How to get the db column and value from Mybatis?

myBatis select to existing object

Is it possible to run a select query that updates an existing java object with myBatis.
For example given this existing java object:
Customer{
int id;
String firstName;
String lastName;
}
lets say I already have a Customer instance C with an Id of 1.
how can I run a myBatis select query that will update that instance rather than create a new instance.
If you need to update the object in memory, you would have to setter each attribute of the object in memory with the result of the query.
Customer customer = new Customer(1,"C",null);//Object in memory
Customer customerQuery = selectQueryMyBatis(); //Query object
customer.setFirstName(customerQuery.getFirstName());
customer.setLastName(customerQuery.getLastName());

JPA Table for Instanzvariable

I have this entity
#Entity
public class Measurement implements Serializable {
#ID
Long id;
double value;
String meter;
}
I would like to create an own table for each "Meter"(One per different value of the instanzvariable) . Is there Way to realise this with JAP?
Why even create a table for each object? Do you understand the meaning of relational databases and how to map an object?
What you need for this is a table "measurements" with columns id, value, meter.Each row will be a new set of values.
If you want to distinct "meters" then create a table "meter" , put values there and use foreign keys from table "measurements".
Maybe you should read something like this "http://www.ntu.edu.sg/home/ehchua/programming/sql/Relational_Database_Design.html"

JPA Error : The entity has no primary key attribute defined

I am using JPA in my application. In one of the table, I have not used primary key (I know its a bad design).
Now the generated entity is as mentioned below :
#Entity
#Table(name="INTI_SCHEME_TOKEN")
public class IntiSchemeToken implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name="CREATED_BY")
private String createdBy;
#Temporal( TemporalType.DATE)
#Column(name="CREATED_ON")
private Date createdOn;
#Column(name="SCH_ID")
private BigDecimal schId;
#Column(name="TOKEN_ID")
private BigDecimal tokenId;
public IntiSchemeToken() {
}
public String getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getCreatedOn() {
return this.createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public BigDecimal getSchId() {
return this.schId;
}
public void setSchId(BigDecimal schId) {
this.schId = schId;
}
public BigDecimal getTokenId() {
return this.tokenId;
}
public void setTokenId(BigDecimal tokenId) {
this.tokenId = tokenId;
}
}
Here In my project, eclipse IDE shows ERROR mark(RED colored cross) on this class and the error is "The entity has no primary key attribute defined".
Can anyone tell me, How to create an entity without primary key ?
Thanks.
You can't. An entity MUST have a unique, immutable ID. It doesn't have to be defined as a primary key in the database, but the field or set of fields must uniquely identify the row, and its value may not change.
So, if one field in your entity, or one set of fields in your entity, satisfies these criteria, make it (or them) the ID of the entity. For example, if there is no way that a user can create two instances in the same day, you could make [createdOn, createdBy] the ID of the entity.
Of course this is a bad solution, and you should really change your schema and add an autogenerated, single-column ID in the entity.
If your Primary Key(PK) is a managed super class which is inherited in an entity class then you will have to include the mapped super class name in the persistence.xml file.
Look at the bug report:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=361042
If you need to define a class without primary key, then you should mark that class as an Embeddable class. Otherwise you should give the primary key for all entities you are defining.
You can turn off (change) validation that was added.
Go to workspace preferences 'Java Persistence->JPA->Errors/Warnings' next 'Type' and change 'Entity has no primary key' to 'Warnning'.
In addition to http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#No_Primary_Key you can use some build-in columns like ROWID in Oracle:
Oracle legacy table without good PK: How to Hibernate?
but with care:
http://www.orafaq.com/wiki/ROWID
Entity frameworks doesn't work for all kind of data (like statistical data which was used for analysis not for querying).
Another solution without Hibernate
If
- you don't have PK on the table
- there is a logical combination of columns that could be PK (not necessary if you can use some kind of rowid)
-- but some of the columns are NULLable so you really can't create PK because of DB limitation
- and you can't modify the table structure (would break insert/select statements with no explicitly listed columns at legacy code)
then you can try the following trick
- create view at database with virtual column that has value of concatenated logical key columns ('A='||a||'B='||'C='c..) or rowid
- create your JPA entity class by this view
- mark the virtual column with #Id annotation
That's it. Update/delete data operations are also possible (not insert) but I wouldn't use them if the virtual key column is not made of rowid (to avoid full scan searches by the DB table)
P.S. The same idea is partly described at the linked question.
You need to create primary key ,If not found any eligible field then create auto increment Id.
CREATE TABLE fin_home_loan (
ID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (ID));
Just add fake id field.
In Postgres:
#Id
#Column(name="ctid")
String id;
In Oracle:
#Id
#Column(name="ROWID")
String rowid;