I have a JPA entity which I want audited. I added Envers to my project, and added the #Audited annotation to the entities I need. Now, the changes are being logged in the audit tables, but I cannot retrieve them through the audit readers provided by Envers.
My entity is as follows.
#Entity
#Audited
#AuditTable(value = "blog_posts_AUD")
#Table(name = "blog_posts")
public class Post {
...
}
I'm trying to query the audit tables as follows.
AuditReader reader = AuditReaderFactory.get(entityManager);
List revisions = reader.getRevisions(Post.class, primaryKey);
This fails, because the SQL call contains a reference to a table called org.foo.bar.blog_posts_AUD, which obviously does not exist. It seems that Hibernate is not picking up the #AuditTable annotation (or the default audit table suffix, for that matter). Anyone ever faced this before?
I have the following jpa/hibernate/hsqldb configuration:
JPA ddl-auto: create-drop
Hibernate entities have no #Table annotation and created with SpringPhysicalNamingStrategy. So, PersonalData entity table name is personal_data. Hibernate creates them due to running the application
hsql DB URL is jdbc:hsqldb:mem:testdb;sql.syntax_pgs=true
My problem is when I try to select due spring repositories with the hsql there is the error about non-existing PERSONAL_DATA table.
I found that this is SQL notation to use CASE_SENSETIVE tables and hqsl follows that. To resolve that developers offer quote table names in sql.
So, I have 2 unlikely ideas
Add #Table annotation to entities.
Override SpringPhysicalNamingStrategy
Is there a way to use a simple property?
I am generating MySQL table by Hibernate as follows:-
#Entity
#Table(name = "buyerPartyDetails")
public class BuyerPartyDetails {
.......
}
But in MySQL the actual table name is as buyerpartydetails I was expecting it should be buyerPartyDetails. How do I force hibernte to genarate table name as my espection?
You can force Hibernate to quote the identifiers by setting:
hibernate.globally_quoted_identifiers=true
or
hibernate.globally_quoted_identifiers_skip_column_definitions=true
which will generate quoted table names in DDL. It might however require SET GLOBAL SQL_MODE=ANSI_QUOTES; as by default MySQL uses backticks ` to quote the names.
OK, I'm trying to connect my SpringBoot application via JPA (Hibernate) to a legacy AS/400 DB database. The table names however have a "." (Period) in them.
ex: LE.ONFP is the table name.
Hibernate however is converting the period to an underscore which causes an error because there is not table called "le_onfp".
#Entity
#Table(name = "\"LE.OFNP\"", schema = "QS36F")
Here is my annotations at the beginning of my Entity class.
adding the following line to my application.properties files fixed my issue.
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
and keeping my annotation the same.
#Table(name = "\"LE.OFNP\"", schema = "QS36F")
I am trying to set a JPA mapping with JoinTable, and it seems to be ignored when Hibernate (my JPA implementation) is doing a query.
To explain the use case
Each time a user gets a page of my app, I insert a line in the USAGE_LOG table (with the id of the user and the id of the page).
Each page is related to a category (for instance: settings, orders, items, news...) and a type (for instance create, update, display, delete).
So, I have some kind of middle entity table, that links a page to: a category + a type. Like a triplet: (page, category, type)
My table structure
table USAGE_LOG (for information only, this one works well)
ID PrimaryKey
USER_ID Foreign key to column ID of table USER
USAGE_LOG_PAGE_ID Foreign key to column ID of table USER_LOG_PAGE
table USAGE_LOG_PAGE
ID PrimaryKey
URL VARCHAR
USER_ACTION_ID Foreign key to column ID of table USER_ACTION
table USER_ACTION
ID PrimaryKey
ACTION_CATEGORY_ID Foreign key to column ID of table ACTION_CATEGORY
ACTION_TYPE_ID Foreign key to column ID of table ACTION_CATEGORY
table ACTION_CATEGORY
ID PrimaryKey
NAME VARCHAR
table ACTION_TYPE
ID PrimaryKey
NAME VARCHAR
So the USER_ACTION table is a join table with the particularity that it links a USAGE_LOG_PAGE to a ACTION_CATEGORY and a ACTION_TYPE at the same time.
Also, I can have several USAGE_LOG_PAGE that are linked to the same ACTION_CATEGORY and ACTION_TYPE.
Unfortunately, I cannot change the database structure (it is legacy code).
I have tried the following Mappping on the Entity "UsageLogPage"
#ManyToOne
#JoinTable(name="action",
joinColumns=#JoinColumn(name="ID", referencedColumnName="USER_ACTION_ID"),
inverseJoinColumns=#JoinColumn(name="ACTION_CATEGORY_ID", referencedColumnName="ID"))
#Getter #Setter
private ActionCategory actionCategory;
#ManyToOne
#JoinTable(name="action",
joinColumns=#JoinColumn(name="ID", referencedColumnName="USER_ACTION_ID"),
inverseJoinColumns=#JoinColumn(name="ACTION_TYPE_ID", referencedColumnName="ID"))
#Getter #Setter
private ActionType actionType;
(I use Lombok for #Getter and #Setter)
This mapping compiles, but when I try to get data, I have the following exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'usagelogpa0_.actionCategory' in 'field list'
Indeed, the Hibernate query is:
select usagelogpa0_.ID as ID1_80_0_,
usagelogpa0_.actionCategory as actionCa2_80_0_,
usagelogpa0_.actionType as actionTy3_80_0_,
usagelogpa0_.URL as URL5_80_0_
from usage_log_page usagelogpa0_
where usagelogpa0_.ID=?
(the key part is the "actionCategory" and "actionType" in the select)
This is not what I expect, Hibernate should do a join.
Have you any idea of what I did wrong?
Thanks !
After lots of investigations, I have found that:
it wasn't working as expected because I put the #ManyToOne and the #JoinTable annotations at the attribute level. I created a getter by hand and put the annotations on it, and they were taken into account
it still wasn't working correctly, because Hibernate didn't find the column "USER_ACTION_ID" on the USAGE_LOG_PAGE table, at run time. This column wasn't in the available fields, for a reason (that I coudn't find). When adding a field "usage_action_id" in the entity "UsageLogPage", it found the attribute, but refused to create the mapping because USAGE_ACTION_ID isn't a primary key.
At the end, even if I couldn't change the database, I could change the object model.
So I created the middle entity "UserAction", binded it with ManyToOne on the UsageLogPage entity, removed the attribute "actionCategory" and "actionType" from the UsageLogPage and added them as ManyToOne in the new UserAction entity.
If you have a table that acts as a middle entity for 2 different ManyToOne relationships, perhaps the best solution is to create the middle entity in your object model.