I have a problem with my code (obviously) and after many searches on Internet, I don't find an answer to my problem, so I ask my question here.
I have this :
#Entity
public class Resident
{
/** Attributes */
#EmbeddedId
private IdResident idResident;
...
#Embeddable
public class IdResident {
#Column(name="NOM")
private String nom;
#ManyToOne
#JoinColumn(name="CODE")
private Port port;
...
#Entity
public class Port
{
/** Attributes */
#Id
#Column(name="CODE")
private String code;
#Column(name="NOM")
private String nom;
...
And I'm using Maven, I've write this in my persistence.xml :
<class>beans.Port</class>
<class>beans.Resident</class>
But when i run the program, no matter what i've write, I have this :
Exception Description: The mapping [port] from the embedded ID class
[class beans.IdResident] is an invalid mapping for this class. An embeddable class that
is used with an embedded ID specification (attribute [idResident] from the source
[class beans.Resident]) can only contain basic mappings. Either remove the non
basic mapping or change the embedded ID specification on the source to be embedded.
I don't see where is my mistake, I think it's because of the IdResident class wich has an Entity object in it, but I don't know how to fiw it
Error message you get explains it quite well, Embeddable that is used as an embedded id can contain only basic mappings, not relationships. In JPA 2.0 specification this is told with following words:
Relationship mappings defined within an embedded id class are not
supported.
Just define attributes that are part of composite id in embeddable that is used as embedded id, and map relationships in entity itself (or in another embeddable and include mappings with #Embedded).
In my opinion this is based on the ManyToOne mapping in the IdResident class cause the error message pushs me into this direction.
Related
I would like Hibernate to disable certain classes from being validated on startup.
My particular use-case:
spring.jpa.hibernate.ddl-auto=validate
#Table (name = "SAME_TABLE")
public class Entity1 {
#Column
private Long value;
// rest of values
}
#Table (name = "SAME_TABLE")
public class SearchEntity2 {
#Column
private String value;
// rest of values
}
As you can see I have two classes mapped to the same table called SAME_TABLE. This is because I want to do wildcard searches on numeric field value
JPA Validation fails on Oracle (h2 succeeds suprisingly) because it detects that the String is not NUMERIC(10).
This question here by #b0gusb provides an excellent way of filtering out via table name:
How to disable schema validation in Hibernate for certain entities?
Unfortunately my table name is identical. Is there any way of getting to the Java class name from SchemaFilteror perhaps another way of doing this?
Thanks
X
I have tried omitting the #Embedded annotation and still the fields have been embedded in the table. I cannot find anything which would say that the #Embedded annotation is optional.
Is it or is it not optional?
The following code
#Embeddable
public class Address {
String city;
String street;
}
#Entity
public class Person {
String name;
#Embedded // it seems that it works even if this annotation is missing!?
Address address;
}
generates always the same table
person
name
city
street
even if I do not specify #Embedded.
My configuration:
JBoss EAP 6.4.0
hibernate-jpa-2.0-api-1.0.1.Final-redhat-3.jar
The JPA specification says:
http://docs.oracle.com/javaee/7/api/javax/persistence/Embedded.html
#javax.persistence.Embedded
Specifies a persistent field or property of an entity whose value is an instance of an embeddable class. The embeddable class must be annotated as Embeddable.
http://docs.oracle.com/javaee/7/api/javax/persistence/Embeddable.html
#javax.persistence.Embeddable
Specifies a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity.
In case of using Hibernate it does not matter if you annotate the field itself (as #Embedded) or if you annotate the referenced class (as #Embeddable). At least one of both is needed to let Hibernate determine the type.
And there is a (implicit) statement about this inside the Hibernate documentation, take a look here:
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#mapping-declaration-component
It says:
The Person entity has two component properties, homeAddress and
bornIn. homeAddress property has not been annotated, but Hibernate
will guess that it is a persistent component by looking for the
#Embeddable annotation in the Address class.
Embedded-Embeddable is not mandatory, but it gives you nice OOP perspective of your entities' relationship. Another way to do such a thing - is to use OneToOne mapping. But in such a case entity WILL be written to separate table (while in case of embedded it CAN be written to the separate table in your DB).
when I use the JPA #Version annotaton in an #Embeddable I get the following exception pointing at my Updateable class:
org.hibernate.AnnotationException: Unable to define #Version on an embedded class
Here is my code:
#Embeddable
public class Updateable {
#Version
private long modcount;
private String updatedBy;
private DateTime updatedAt;
// getters & setters
}
#Entity
public class SomeEntity {
#Id
private Long id;
#Embedded
private Updateable updateAudit;
// other stuff
}
Is it not possible to have a #Version in an #Embeddable, or is this Hibernate specific?
An embeddable class is just a convinience way of declaring reusable entity elements, i.e. your Updateable could be used in other entities without having to add the fields and the mapping again.
As such, embeddables are part of the entity (as the name suggests they are embedded) and thus independent versioning doesn't make sense.
Adding the #Version annotation to the embeddable only would also not make much sense since the embeddable itself can't be versioned and you'd have to deal with cases where multiple embeddables are contained in a single entity (e.g. which version should be used in that case?). So since #Version only makes sense for entities it's easier to just allow that annotation for entities or mapped superclasses.
Actually although the JPA spec recommends that version properties are numeric, strings or timestamps Hibernate seems to provide user defined version types:
The version column may be a numeric (the recommended solution) or a timestamp. Hibernate supports any kind of type provided that you define and implement the appropriate UserVersionType.
So what you might be able to do (not tested, just derived from the docs) if you want to use Updateable as your version is to provide a custom user type for Updateable and then use it like this:
#Entity
public class SomeEntity {
#Id
private Long id;
#Type( "your.custom.UserVersionType" )
#Version
private Updateable updateAudit;
// other stuff
}
I'm developing an Java-application which stores its data via Hibernate in a database.
One feature of this application is to define templates like types, etc. for reuse. For instance the type has attributes and you can create instances of an type, which has values for the attributes.
The problem is, that I don't know how to ensure that only values for attributes can assigned which the type defines. In my solution there is a redundancy which cause the problem, but I don't know how to remove it.
My current (and problematic) approach looks like this:
#Entity
class Type
{
#Id
#Generated
private Long id;
#OneToMany(mappedBy="type")
private List<Attribute> attributes;
//...
}
#Entity
class Attribute
{
#Id
#Generated
private Long id;
#ManyToOne
private Type type;
//...
}
#Entity
class Instance
{
#Id
#Generated
private Long id;
#ManyToOne
private Type type;
//...
}
#Entity
class AttributeValue
{
#Id
#Embedded
private ResourceAttributValueId id;
#Column(name="val")
private String value;
//...
}
#Embeddable
public class ResourceAttributValueId implements Serializable
{
#ManyToOne
private ResourceStateImpl resource;
#ManyToOne
private ResourceAttributeImpl attribute;
//...
}
There the definition of the type is redundant: Type can be reached via AttributeValue->Attribute->Type and AttributeValue->Instance->Type
Another idea was to use type + attribute name as id of the attribute and instance + attribute name as id of the attribute value, but that doesn't solves my problem.
The key for correctly modeling "diamond-shaped" dependencies like this is the usage of identifying relationships:
(I took a liberty of renaming your entities slightly, to what I believe is a more consistent naming scheme.)
Note how we migrate the TYPE_ID from the top of the diamond, down both sides, all the way to the bottom and then merge it there. So, since there is only one ATTRIBUTE_INSTANCE.TYPE_ID field and is involved in both FKs, we can never have an attribute instance whose attribute type's type differs from instance's type.
While this avoids "mismatched" attributes, it still doesn't ensure the presence of attribute instances (if you support the concept of "required attribute"), which is best enforced at the application level. Theoretically you could enforce it at the database level, using circular deferred FKs, but not all DBMSes support that, and I doubt it would play nicely with ORMs.
Unfortunately, I'm not experienced enough with Hibernate to answer whether this can be mapped there and how.
See also:
Choosing from multiple candidate keys
How to keep foreign key relations consistent in a “diamond-shaped” system of relationships
I'm currently working on a project that involves the use of Hibernate Search. Currently the project uses pure SQL for its searches and we would like to use a text search instead (Needing to know and correctly spell the first word can get annoying).
The schema is that a product can have multiple versions and the current version contains the name of the product.
Public Class Product extends ProgEntity
{
private List<ProductVersion> versions = new ArrayList<ProductVersion>();
...
}
Public Class ProductVersion extends ProgEntity
{
String productName;
...
}
I need to be able to search for a product based on its name. I was able to index the ProductVersions by productName with little issue however indexing Product is proving to be more of an issue.
After some research this is what I have however when I update the product to the DB no index is created.
#Entity
#Indexed
Public Class Product extends ProgEntity
{
#IndexedEmbedded
private List<ProductVersion> versions = new ArrayList<ProductVersion>();
...
}
#Entity
#Embeddable
Public Class ProductVersion extends ProgEntity
{
#Field
String productName;
...
}
The DocumentID is part of ProgEntity. I need to be sure that if I update Product or Product Version that it will be indexed properly which does not seem to be happening now.
Any suggestions on what I am doing incorrectly?
You don't have a relationship (eg many-to-one, many-to-one) between Product and ProductVersion mapped in the code you posted. This relationship must be bi-directional. Annotate the Product's collection field with #IndexedEmbedded, and the inverse field on the ProductVersion side with #ContainedIn, and you should be all set.
Using #Entity and #Embeddable on ProductVersion seems wrong. There are also some JPA annotations missing. Is the version collection mapped as #ManyToOne or #ElementCollection.
Have you checked your hibernate configuration and log files? Which directory provider are you using?