I'm using JPA to persist my data and have one column that is #embedded and refers to a class that is #embeddable.
When my job runs the tables are created in the schema I specify via the #table annotation. But the data for the #embeddable objects are written in the default schema. I do not see any property to set the schema for the #embeddable tables.
Hope you can point me in the right direction!
The answer seems to be to add the annotation #CollectionTable.
Related
I'm currently using Hibernate & Envers version 5.2.9.Final. I want to use #ElementCollection with a custom table name for both the collection and the audit table.
What I know so far is that modifying default table names has a variety of annotations to work with: For the entity itself there are the annotations #Table and #SecondaryTable as well as the corresponding envers annotations #AuditTable and #SecondaryAuditTable. For changing the table name of an element collection there is the #CollectionTable annotaion. I have not been able to find a corresponding envers annotation so far. So my question is:
How can I change the name for a hibernate #ElementCollection envers audit table?
Additional info
In the hibernate envers ticket which tracks the adding of auditing support for element collections, the same question was asked back in 2013 but not answered.
A code snippet to make my setup clear:
#Entity
#Table(name = "\"user\"")
#SecondaryTable(name = "\"user_secondary\"")
#Audited
#AuditTable("\"user_audit\"")
#SecondaryAuditTable(secondaryTableName = "user_secondary",
secondaryAuditTableName = "\"user_secondary_audit\"")
public class User {
// ... stuff like id and other fields ...
#ElementCollection
#CollectionTable(name = "\"user_references\"")
private Map<String, Long> references = new HashMap<>();
// TODO FIXME how to get a custom name for the audit table?
// ... more stuff like getters and setters
}
Hibernate generates all tables as intended, yet the collecction audit table is named 'user_references_AUD' while I would like to get the name 'user_references_audit' like for the other tables.
I'm also aware of the global settings affecting the audit table prefix or suffix, but that is only a last resort for my use case.
Update
As suggested I added a feature request to Hibernate JIRA.
That is because Envers has no complement for #CollectionTable.
You are welcomed to add a JIRA requesting that we add a complementing annotation and I can look at what is needed to add the functionality. Just at a glance, it shouldn't require too much as it merely needs to feed into the generated Envers entity table name for the collection middle entity.
In a spring mvc app using hibernate, jpa, and MySQL, I have a BaseEntity that contains an id field that is unique across all classes that inherit from BaseEntity, using #Inheritance(strategy = InheritanceType.TABLE_PER_CLASS). Some data is imported into the MySQL database using an external dml.sql file run from the command line. The imported data is carefully planned so that all the ids that need to be managed as part of the BaseEntity inheritance group are unique within their inheritance group.
The problem is that hibernate is not taking the values of the ids already in the database into account when it inserts a new record into the database. Instead, hibernate is saving an id value in one of the descendent entities which is identical to an id stored in one of the other descendent entities.
How can I configure hibernate to respect the id values already in the database when it saves a new entity within the same inheritance group?
Some relevant facts are:
All of the objects in the MySQL database were created directly from the hibernate mappings in the app by using hbm2ddl.
I cannot use #MappedSuperClass for BaseEntity because BaseEntity is used as a property of one of the entities in the app, so that entities of various types can be stored in the same property of that entity. When I was using #MappedSuperClass, eclipse was giving compile errors saying that BaseEntity cannot be instantiated directly because it has #MappedSuperClass annotation.
Note: The file sharing site seems to be center-justifying all the code. You can fix this by simply cutting and pasting it into a text editor.
You can read the code for BaseEntity by clicking on this link.
The code for the entity whose id values are being set incorrectly by hibernate can be read by clicking on this link.
The jpql code for saving the entity whose id is being set incorrectly is as follows:
#Override
#Transactional
public void saveCCD(HL7ConsolidatedCareDocument ccd) {
if (ccd.getId() == null) {
this.em.persist(ccd);
this.em.flush();
}
else {
this.em.merge(ccd);
this.em.flush();
}
}
I have never done this using hibernate or mysql ut have done something similar with EclipseLink + PostgreSQL. So there might be some mistakes below.
With generation type TABLE you might want to explicitly specify some additional parameters using the TableGenerator annotation. That way you are certain where hibernate is storing things.
#Id
#GeneratedValue(
strategy=GenerationType.TABLE,
generator="TBL_GEN")
#javax.persistence.TableGenerator(
name="TBL_GEN",
table="GENERATOR_TABLE",
pkColumnName = "mykey",
valueColumnName = "hi"
pkColumnValue="BaseEntity_Id",
allocationSize=20
)
What you need to do when you bypass hibernate is to reserve the ids you need by updating the row with mykey BaseEntity_Id in the table GENERATOR_TABLE.
For details on the annotations see paragraph 5.1.2.2
I want to populate the table after his generation from the #Entity Class.
I want to know if this is possible with JPA and how can I do it .
Unfortunately, Hibernate has #Generated annotation but JPA doesn't have it and there is no alternative to it. You can also try to apply #PrePersist annotation before EntityManager persists your object.
I have some tables in db(postgresql) with names like this "Test".When i try create java classes from this tables with hibernate its not happening. I get classes from tables with names like this test. How to make hibernate can see tables with quotes in names?
UPDATE
Maybe i write question not correct. But i cant create java classes and i want to know how to do reverse ingenering with tables which have names in qoutes. I cant delete qoutes from table names and column names couse they have names like Type and Full.
By default, Hibernate assumes the database table name is the same as the class name, but you can override this behaviour via the #Table annotation:
#Entity
#Table(name="\"Test\"") // Will use "Test" (including the quotes) as the table name
public class Test {
The #Table annotation is used to specify the table to persist the data. The name attribute refers to the table name. If #Table annotation is not specified then Hibernate will by default use the class name as the table name. So your database's table name is "Test" then you should use your class name is "Test".
Please check your database with
select * from """Test""" if your table name is "Test".
Your entity class should be
#Entity
#Table(name = "\"\"\"Test\"\"\"")
public class Test {
}
It seems that you are not using annotations as of now...
So in case you want to use "Test" as table name you should define the mapping of POJO with your table either via annotations as defined by Bohemian
#Entity
#Table(name="\"Test\"")
public class Test {
or define in the Test.hbm.xml in which you have to map your table and fields to java class and columns.
Alternately, you can specify the schema and database name inside #Table annotation.
#Entity
#Table(name = "Test", schema = "public", catalog = "TestDatabase")
Hibernate will recognize the table without the need to escape double quotes.
If I have an entity such as the following:
#Entity
public class Customer {
private Address address;
}
And the Address is also an entity:
#Entity
public class Address {...}
Does persisting the Customer in turn persist its contained Address? Or is this not possible at all? The idea was basically to have a main entity that consists of its fields, some of which are entities themselves that will be stored in individual tables. Some of the fields of Customer are unique in that I also would like a Customer table for that data. Unless I'm just missing it, I haven't been able to find this answer. This was something I was just curious about and I'm not currently on a machine where I can try it, so I wanted to ask first.
Thanks in advance.
This is possible and JPA basics. But you have to define the associations between entities in your entity classes.
I recommend reading a good tutorial on this topic, e.g. the Java EE6 tutorial.
You have 2 options depending on your domain model:
removing the #Entity from address and annotate it with #Embeddable
mapping the Address in the Person with: #OneToOne(cascade = {CascadeType.PERSIST})