JPA Table for Instanzvariable - jpa

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"

Related

QueryDsl in JSONB column postgresql

I have an object which has jsonb column. Is there any way to query into this jsonb column using querydsl?
Here is an example of my objects:
public class Person {
#Type(type = "jsonb")
#Column(columnDefinition = "jsonb")
private PersonDocument personDocument;
}
public class PersonDocument {
private int documentType;
private List<DocumentDetail> documentDetails;
}
public class DocumentDetail {
private String country;
private String documentId;
private LocalDate expiryDate
}
I would like to search person by documentId, so I need to get to documentId column
QueryDSL doesn't have any support for queries on PostgreSQL jsonb column. I have one solution that works for Query on the PostgreSQL field using QueryDSL.
solution steps:
Create a database view using the table where jsonb column. The view uses to convert your jsonb to the table normal table structure. like table A(j jsonb) now you want the field "xyz" from "j" jsonb column from A table. you can apply the following query:
CREATE OR REPLACE VIEW view_b as select a.id as a_id,a->> "xyz" as xyz from A a
now, view table structure like view_b(a_id,xyz)
Now you create a domain object which represents this view.
#Table(name="view_b") public class ViewB{...}
now you can query using query DSL. like qViewB.xyz.eq("value")

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?

How exactly work the #OneToMany JPA annotation in this example? Is it related to a table column or an entity class field?

I have 2 DB tables named respectivelly T_ACCOUNT and T_ACCOUNT_BENEFICIARY.
These tables have the following structure:
create table T_ACCOUNT (ID integer identity primary key, NUMBER varchar(9), NAME varchar(50) not null, CREDIT_CARD varchar(16), unique(NUMBER));
create table T_ACCOUNT_BENEFICIARY (ID integer identity primary key, ACCOUNT_ID integer, NAME varchar(50), ALLOCATION_PERCENTAGE decimal(5,2) not null, SAVINGS decimal(8,2) not null, unique(ACCOUNT_ID, NAME));
And the T_ACCOUNT table is bound to the T_ACCOUNT_BENEFICIARY table with a one to many relationship, this is the graphical representation:
So this is the first class named Account that map the T_ACCOUNT table:
#Entity
#Table(name="T_ACCOUNT")
public class Account {
#Id
#GeneratedValue
#Column(name="id")
private Long entityId;
#Column(name="NUMBER")
private String number;
#Column(name="NAME")
private String name;
#OneToMany
#JoinColumn(name="ACCOUNT_ID")
private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();
#Column(name="CREDIT_CARD")
private String creditCardNumber;
// GETTERS & SETTERS
}
And this is the Beneficiary class that map the T_ACCOUNT_BENEFICIARY table:
/**
* A single beneficiary allocated to an account. Each beneficiary has a name (e.g. Annabelle) and a savings balance
* tracking how much money has been saved for he or she to date (e.g. $1000).
*/
#Entity
#Table(name="T_ACCOUNT_BENEFICIARY")
public class Beneficiary {
#Id
#GeneratedValue
#Column(name="ID")
private Long entityId;
#Column(name="NAME")
private String name;
#Embedded
#AttributeOverride(name="value",column=#Column(name="ALLOCATION_PERCENTAGE"))
private Percentage allocationPercentage;
#Embedded
#AttributeOverride(name="value",column=#Column(name="SAVINGS"))
private MonetaryAmount savings = MonetaryAmount.zero();
As you can see into the Account I have the beneficiaries field that implement the one to may relationship
#OneToMany
#JoinColumn(name="ACCOUNT_ID")
private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();
I know that, on the DB, this relationship is implemented by the ACCOUNT_ID field of the T_ACCOUNT_BENEFICIARY table (so multiple row of the T_ACCOUNT_BENEFICIARY table can have the same value of the ACCOUNT_ID field and this means that a single row of the T_ACCOUNT table can be associated to more than one rows of T_ACCOUNT_BENEFICIARY table).
As you can see in the previous sippet there is the #JoinColumn(name="ACCOUNT_ID") annotation.
My doubt is generated by the fact that I have an ACCOUNT_ID column on my T_ACCOUNT_BENEFICIARY table, infact:
create table T_ACCOUNT_BENEFICIARY (ID integer identity primary key, ACCOUNT_ID integer, NAME varchar(50), ALLOCATION_PERCENTAGE decimal(5,2) not null, SAVINGS decimal(8,2) not null, unique(ACCOUNT_ID, NAME));
but this column seems to not be mapped on the Beneficiary that map this T_ACCOUNT_BENEFICIARY table.
So my doubts is: the #JoinColumn(name="ACCOUNT_ID") is working at relational level performing the join operation on the ACCOUNT_ID column of the table mapped by the Beneficiary entity (T_ACCOUNT_BENEFICIARY) or am I missing something? How exactly is performed this join?
If my interpretation is right can I work at entity level and say to join the beneficiaries field of my Account entity class to a new accountId field inserted into my Beneficiary entity class and mapping the ACCOUNT_ID column of the T_ACCOUNT_BENEFICIARY table?
Tnx
It seems is a Unidirectional OneToMany relationship
In JPA 2.0 a #JoinColumn can be used on a OneToMany to define the foreign key
I'm not sure if I understand your question. But what you have done with your #JoinColumn annotation is correct and Hibernate will execute appropriate SQL statements when you have multiple beneficiaries for your account. For example executing multiple INSERTS if you have two Beneficiaries for an Account. And yes using the #JoinColumn annotation is at the hibernate level. If you want to access an Account from a Beneficiary entity you would need to define a Bidirectional relationship in the Beneficiary class like below.
#Entity
#Table("T_ACCOUNT_BENEFICIARY")
public class Beneficiary {
#ManyToOne(mappedBy = "beneficiaries")
Account account;
...
}

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;

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

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.