Here's my problem : i have two databases, with one containing tables that i will need in the second one. These tables are lists for many-to-one relationships, so they won't be updated frequently, but it's still a possibility.
So in order to not duplicate my tables i wanted to use a foreign data wrapper, create foreign tables that map them, and then create views that map these foreign tables. I want these views because i need to set specific privileges depending on the role of the user (something you can't do with foreign tables right ? You can only set an owner ?)
Anyway, now i have my views, and now i created Java classes so that Hibernate can map the tables.
My questions :
1/ Is it bad practice to use #Id #JoinColumn on classes that are mapping views ? Because they don't have primary or foreign keys. Will it end in lack of performances ?
2/ Am i completly missing something, and maybe there is another database design that could solve my problem ? Knowing that i can't merge my two datables and create two separate schemas.
Thanks in advance !
Related
I've seen many examples and real-life projects where database table columns have a unique prefix that corresponds to the table name. Small example:
CREATE TABLE customers (cus_id BIGINT, cus_name VARCHAR(255), cus_adr_id BIGINT);
CREATE TABLE addresses (adr_id BIGINT, adr_postcode CHAR(5));
How can I accomplish this in Hibernate or JPA?
I already tried to implement PhysicalNamingStrategy but that doesn't seem to have access to the entity itself so I have no way to know the entity when setting the column name.
I now hope that there is a better way than placing annotations above every single variable declaration. That's pretty verbose and doesn't fit to my expectations to ORM which in my eyes should ideally provide an automatic way of mapping. Moreover, the ID and other properties that are shared among entities I have to keep in a base-class entity which makes the annotations even more complicated.
I'm looking for some suggestions for best practices around modeling the relationship between various entities and their documents (binaries such as PDF, TIFF etc). The entities are standard JPA/Hibernate stored in a PostgreSQL database. The documents themselves will be stored in MongoDb database.
The plan is to create a child entity to represent the document, which contains the id to the binary data to retrieve it as needed. But what would the relationship be?
If I simply created one if these document entities for each parent entity then a simple one to many relationship would work, but that seems to redundant.
I could simply put a "type" column that indicates which entity the document belongs to, and then query the document table with a named query of "id = ? and type = ?". I guess that would work, but there is something about that I'm not crazy about either - just can't put my finger on it :) Maybe that's just fine.
Another option I have looked at (although I admit I have never used it before, and would need to study it a bit more) is to use a unidirectional one to many with join table. However, I don't think this will work either since there is no guarantee that there wouldn't be duplicate parent keys. I use a single sequence for all basic relation tables primary keys, which should guarantee it, but it still doesn't sound like a good idea.
Finally, I have considered whether I create an entity and then extend it for each parent entity, but I think that would have the same flaw - the theoretical existence of non-unique parent ids.
Before I make a final decision, I'd like to see what other suggestions the community might have to offer.
Thanks in advance for your ideas.
If I simply created one if these document entities for each parent entity then a simple one to many relationship would work, but that seems to redundant.
I'm a bit confused. If you create a document for each parent, isn't that one-to-one and not one-to-many? It sounds like you want a one-to-many relationship. In which case, you would only create a single document for all parent entities that reference it.
I am thinking about switching from a self-implemented versioning-solution to Hibernate Envers, but I am not quite sure yet. I have read a lot about it, but I am concerned about schema changes and how Envers deals with them after having historized data according to an older schema.
What is your experience with Envers in this regard? How do you deal with schema changes and existing data with Envers?
Update 1:
It is not just about adding removing simple columns from a table, but e.g. when changing a simple Forein-Key-Relationship into a separate entity with two 1:n-relationships (M2M with attributed columns. This is a "logical" change in your data model. How do you deal with that when using Envers, when there is already historized data according to the old model? Is there an alternative to manually write sql-scripts and transfering them into the new representation?
In my experience, Envers simply copies every field from your entity table to its audit tables. The copied fields in the audit tables have no constraints on them, including nullability and foreign key constraints, so there's no problem with adding or removing such constraints on the real tables. Any kind of relationships you add to your entities will just be new audit columns and/or tables added under Envers, and it's up to you to correctly interpret them in their historical context.
For your example, if I understand correctly, of switching from a join-column-based relationship to a join-table-based one, you'd simply have the old join column coexisting with the join table, and at the point of the cutover, the former will cease being populated in favor of the latter. Your history will be completely preserved, including the fact that you made this switch. If you want all the old data to fit into the new model in the audit tables, it's up to you to do the migration.
There shouldn't be problems with modifying the existing schema as Envers relies on your #Entities to create the audit tables. So if you add or remove a column from an existing table, as long as this change is reflected in your #Entity / #Audited JavaBean, it should be ok.
The foreign key refactoring should be fine with Envers. As Envers creates a join table even for one-to-many relationship, it should be straight to change it to become many-to-many relationship. I extracted one paragraph from official document:
9.3. #OneToMany+#JoinColumn
When a collection is mapped using these two annotations, Hibernate
doesn't generate a join table. Envers, however, has to do this, so
that when you read the revisions in which the related entity has
changed, you don't get false results.
To be able to name the additional join table, there is a special
annotation: #AuditJoinTable, which has similar semantics to JPA's
#JoinTable.
One special case are relations mapped with #OneToMany+#JoinColumn on
the one side, and #ManyToOne+#JoinColumn(insertable=false,
updatable=false) on the many side. Such relations are in fact
bidirectional, but the owning side is the collection (see alse here).
To properly audit such relations with Envers, you can use the
#AuditMappedBy annotation. It enables you to specify the reverse
property (using the mappedBy element). In case of indexed collections,
the index column must also be mapped in the referenced entity (using
#Column(insertable=false, updatable=false), and specified using
positionMappedBy. This annotation will affect only the way Envers
works. Please note that the annotation is experimental and may change
in the future.
I am working on converting a legacy system to use hibernate (version 3.3.x) instead of using hand crafted SQL. I have run in to some problems mapping my datamodel that pertians to composite keys. I've created a solution I think works, but I am not overly fond of it. Hence, I would like to see how the diagram below could/should be mapped and see if I am on the "right" track.
In the diagram StuffTypes is a pretty static table that don't change (no inserts or updates). Parent is the only table that currently has a DAO class associated to it (the others should be persisted when the parent instance is). Stuff has a StuffType and a number of SubStuff associated with it. Finally, SubStuff is just a many to many mapping table between Stuff and StuffTypes.
What is the best way of mapping these entities to Java objects using annotations?
Personally, I often refer to the section 3.2 Primary Keys through -ToOne Relationships of the JPA Wiki Book. And read also 3.1 Composite Primary Keys.
Adding a primary key stuff_id to the Stuff table and another primary key substuff_id to SubStuff is less complicated. Composite keys are possible, of course. If seen solutions where #Embeddable classes have been introduced to model the composite keys.
Hibernate Reference is your best bet. Try this, Mapping Entities with Composite Keys.
I've been dealing with composite id's and asked a few questions and I was recommended to replace my composite PK's with a single id column, and to control integrity with indexes... All of this related to the fact that mapping composite id's isn't that simple...
On the other side, some people encourage the usage of composite id's that are accord to the domain model...
So I decided to ask: When will you encourage using composite PK's in your DB while using Hibernate?
I personally favor composite ids because they emerge out of the entity-relationships. However, Hibernate suggests the use of simple integer ids. But I think you don't have to choose one over the other.
You can have your composite id constituent fields to become a <natural-id>
And have a private integral field in the class for hibernate to use as the id.
See http://docs.jboss.org/hibernate/stable/core/reference/en/html/mapping.html#mapping-declaration-naturalid