JPA Entity with partial columns for an Object using Java - java

I have a table which is of kind Ledger which records all information with no unique values.
Name
Date
Statement
First
row
random data
Second
row
random data
I am trying to create an Entity which will only fetch name and statement
#Entity
public class MyTable {
private String name;
private String statement;
}
As I am not specifing #Id I am getting exception and We don't have any unique identifier in the table I can't mention #Id annotation.
Also, If we need to write any user defined method for getting these values please suggest how to do that as well.Any sources or samples will greatly help here.

As you don't have any unique identifier, you need to define that first.
You can do it in two ways:
Redesign the table and identify any column which is unique Or
Declare a Long value as a unique identifier like this[works for mysql, for pg, you need to define a sequence for auto id generation]:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Moreover, to get values, don't forget to add getters setters method for these fields.

Related

Mapping recursive relation via secondary table with Spring Data

I have database such as this:
CREATE TABLE unit
(
id INTEGER NOT NULL,
name VARCHAR,
);
CREATE TABLE unit_composition
(
parent_id INTEGER NOT NULL,
child_id INTEGER NOT NULL,
quantity INTEGER,
CONSTRAINT child_fk FOREIGN KEY (parent_id)
REFERENCES public.refdse (id) MATCH SIMPLE,
CONSTRAINT parent_fk FOREIGN KEY (parent_id)
REFERENCES public.refdse (id) MATCH SIMPLE
);
ALTER TABLE unit_composition
ADD CONSTRAINT composit_pk PRIMARY KEY (parent_id, art_nr);
I have a table of manufactory units. Each unit can have multiple sub-units, and sub-units can have multiple sub-sub-units and so on. Also I have a quantity field that shows how many sub-units are needed to manufactor a single unit. So it is kind of a tree relation.
Now I want to map it to classes with Spring Data. I have a Unit class with an Id and Name:
#Entity
#Table(name = "unit")
class Unit {
#Id
#Column(name = "id")
private int id;
#Column(name = "name")
private String name;
...
}
I've created a secondary class Part:
class Part {
private Unit unit;
private int quantity;
...
}
And I need unit class to have a field like List subUnits.
I tried to do it with a #SecondaryTable and #JoinColumn annotations, but I got an error saying "Relation unit_unit does not exist".
Also I tried to make Part an #Entity but it has no Id field.
Alternatively I tried to make #Embeddable class PartId and insert an instance into Part class like this:
#Embeddable
public class PartId implements Serializable {
private Unit parentUnit;
private Unit unit;
I'm getting an error in PartId class saying that "Basic type should not be Persistence Entity" because it's Embeddable and don't have a table assign to it.
So how can I make this work being able to get recursivly all sub-units (with sub-sub-units and so on) of a given Unit? I don't quite get it how can I map an entity that is really just links from table to itself.
So my first solution was to make Jdbc template repository and simply build necessary lists manually via SQL-queries. But I found much better and simplier solution that required adding an id column to unit_composition table and therefore making Part class an #Entity with #ManyToOne relationship to a Unit class. And the rest was simply done by Spring Data.

How to avoid duplicate entries in Postgres database? Entries contain varying value

Method to store entity:
PoolDef poolDef = new PoolDef();
poolDef.setDate_from(date);
poolDef.setName(poolList.getPoolList().get(i).getName());
poolDefRepository.save(poolDef);
Entity itself:
#Setter
#Getter
#EqualsAndHashCode(of = {"Id"})
#Transactional
#Entity
public class PoolDef {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
private String name;
#Column(name = "date_from", columnDefinition = "timestamp with time zone not null")
private OffsetDateTime date_from;
}
The only value that varies is the date_from. I do not know, why new entries are being added to the database and not just get updated. I have the #EqualsAndHashcode that are being built based on primary Id key, so the date_from should not matter. Every method invocation creates a new entry with a completely new Id...
your problem is your
GenerationType.IDENTITY
the documentation says:
Indicates that the persistence provider must assign primary keys for
the entity using a database identity column.
Now the key question is, what SQL is getting generated. Can you please trace the insert SQLs generated?
Also I would prefer to use SEQUENCES of databases. So I do not have to mess around with the Identities of the persistence provider and any application will behave the same against the database if you use the SEQUENCES of databases for your ID/primary key columns.
Also a issue could be your DDL for the table creation, but I assume you know how to define the database tables with the given constraints.

JPA: how to set up key for historizing entities

Within JPA in Spring Boot / Spring Data, I want to set up an entity class.
The business requirement is to historize the processing of documents that exist once per year each.
The processing is performed in a bulk: so all documents are processed together: there is one processingTimestamp for all documents in the database for each processing sequence.
Later on, I want to access only the most recently processed document, but keep the previously processed documents for reference.
I see the following alternatives:
Use a composite key
#Id
private String documentId;
#Id
private String yearOfDocumentCreation;
#Id
private java.sql.Timestamp processingTimestamp;
Use an auto generated key
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String documentId;
private String yearOfDocumentCreation
private java.sql.Timestamp processingTimestamp;
Which alternative is better/best practise regarding
Handling (e.g. storing a list of documents as a bulk that were read before from the database and avoiding duplicates in the database)
Performance
Or do I miss other alternatives/aspects?
I recommend using a single Long primary key, if you will need to make a foreign key to this table.
To avoid dublicates you can make a unique constraint on the 3 required columns.

How to generate auto incremented id for each table separately using SQL Server and Hibernate

I am trying to have separate auto incremented id generator for each of my entities.
The target database is a SQL Server database, and I am using Hibernate 5.2.4.Final. Also I am generating the tables from code.
I have an abstract BaseEntity and other child entities like below, and thus, I am aiming for TABLE_PER_CLASS.
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {
protected long id;
#Id
#GeneratedValue(strategy = GenerationType.XXX)
#Column(name = "Id")
public long getId() {
return id;
}
}
#Entity
#Table(name = "Tags")
public class Tag extends BaseEntity {
}
Below are the different scenarios that I have faced so far:
setting XXX to AUTO: Creates a hibernate_sequence table in database, which I assume, will not provide separate id sequence for separate table.
setting XXX to SEQUENCE: Same as above. Referred this, while doing it.
setting XXX to TABLE: Creates a hibernate_sequences table, which can provide separate id sequence for separate table. However, I have found out that this is quite expensive (same reference as above), and also not my preferred strategy.
setting XXX to TABLE: Does not work for TABLE_PER_CLASS.
What I actually want to use is the native identity column of SQL Server. However, using the SEQUENCE is also an option, but I am not sure how to create and use one for each table from hibernate. Please suggest how either one of these two can be achieved.
Update on the answer by Khalil M. I tried it in 2 possible ways:
applying on BaseEntity -> does not create a separate sequence for each table, and rather creates a ID_SEQNCE, which queried before saving every new entity. So, I am not sure how this is any different than using GenerationType.TABLE.
applying it on each individual entity class -> while saving, the generator creates duplicate id.
for creating a sequence use this
#Id
#GeneratedValue(generator = "ID_SEQ", strategy = GenerationType.SEQUENCE)
#SequenceGenerator(name = "ID_SEQ", sequenceName = "ID_SEQNCE",allocationSize=1)
Edit:
You have to make it by yourself because what you are asking is not supported in Table per class
the id has to be shared across several tables. Consequently, when
using this strategy, you should not use AUTO nor IDENTITY.
for more info
Use strategy = GenerationType.IDENTITY
A short example is below
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", updatable = false, nullable = false)
private Long id;
The GenerationType.IDENTITY is the easiest to use but not the best one from a performance point of view. It relies on an auto-incremented database column and lets the database generate a new value with each insert operation. From a database point of view, this is very efficient because the auto-increment columns are highly optimized, and it doesn’t require any additional statements.

How to store entity with setted UUID?

I'm using MS SQL Server + Hibernate (JPA, more precisely, with EntityManager) and i faced with the problem: I need to store entity into appropriate table in my DB; this table has uniqueidentifier as primary key; and storing entity already has UUID (it's primary key), with witch it should be inserted into the DB.
Problem is that when i try to merge my entity, hibernate do some magic and store my entity with another UUID value. So, when I fetch this entity from db and take a look on it ID, I see inappropriate value.
So, I want to tell hibernate not to do that (or, maybe, there is another solution?).
My entity class:
public class Entity extends BaseEntity {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#Column(name = "id_column")
private UUID uuId;
// other fields, getters, setters
}
Also, I have one more 'annoyance': my IDE and my DB browser shows me another ID in that column. I mean, when I stop my app in the debug mode and look at the id of an entity, I see different value from a value in the database.
Thanks in advance!

Categories

Resources