Embeddable not enhanced with OpenJpa - java

SOLVED
Metadata classes and Entity/Embeddable classes have different names. I just renamed them and now it fires up
I'm trying to map an entity on my DB with my jpa web application. The problem is that the entity got a 2 elements key and, also if i'm using an embeddable, after launching my app with tomcat, it displays this error:
Caused by: <openjpa-2.4.0-r422266:1674604 fatal user error> org.apache.openjpa.util.MetaDataException: The type "class it.cabel.aml.libb2b.cliente.jpa.entities.JpaKeyPK" has not been enhanced.
I'm changing the name of classes just for readability.
This is the JpaKeyPK class:
//import...
#Embeddable
public class JpaKeyPK implements Serializable {
#Column(name = "ID")
private Integer id;
#Column(name = "DATA_VARIAZIONE")
private Date dataVariazione;
public JpaKeyPK () {
}
public JpaKeyPK (Integer id, Date dataVariazione) {
this.id = id;
this.dataVariazione = dataVariazione;
}
// getters, setters, hashcode and equals implementation...
And this is the entity class:
#Entity
#Table(name = "TABLE_NAME")
public class JpaEntity{
#EmbeddedId
private JpaKeyPK pk;
//getters, setters, constructor...
I added both of them to my persistence.xml file and, when i try to do a clean install with maven, logs write this:
12670 App INFO [main] openjpa.Tool - Enhancer running on type "class it.jpa.entities.JpaEntity".
12671 App INFO [main] openjpa.Tool - Enhancer running on type "class it.jpa.entities.JpaKeyPK".
What's wrong?

Related

spring-data-jdbc error Required identifier property not found for class

Getting below error while loading data from database
java.lang.IllegalStateException: Required identifier property not found for class com.sudhirt.practice.springdatajdbcpractice.entity.AuthorRef!
at org.springframework.data.mapping.PersistentEntity.getRequiredIdProperty(PersistentEntity.java:105)
at org.springframework.data.jdbc.core.EntityRowMapper.readEntityFrom(EntityRowMapper.java:143)
at org.springframework.data.jdbc.core.EntityRowMapper.readFrom(EntityRowMapper.java:124)
at org.springframework.data.jdbc.core.EntityRowMapper.lambda$createInstance$0(EntityRowMapper.java:167)
Below is the entity class AuthorRef
#Data
#Table("BOOK_AUTHOR")
#NoArgsConstructor
#AllArgsConstructor
public class AuthorRef {
private Long author;
}
What might be the reason for above error?
Source code is available at https://github.com/sudhirtumati/spring-data-jdbc-sample
You are referencing AuthorRef in a Set inside your aggregate root Book.
public class Book {
#Id
private Long id;
private String name;
// ...
private Set<AuthorRef> authorRefList;
// ...
}
Without an id column Spring Data can't determine a primary key for AuthorRef.
Just adding an #Id annotation to author should be sufficient.
Alternatively you could use a List which will add an additional book_key column which together with the book column form a primary key.

Neo4j: Error for relationship property: Property values can only be of primitive types or arrays thereof

According to https://docs.spring.io/spring-data/neo4j/docs/4.0.0.M1/reference/html/#__relationship_connecting_node_entities I want to save nodes that have a 1:1 relation to another complex node. Used Neo4j version: 3.2.6
Following use case:
For uploaded files specific information about these files are stored into Neo4j as an entity of FileHashEntity
Users who are uploading files are present as user objects in Neo4j: BaseUserEntity and UserEntity
FileHashEntity has a relationship to the user who originally uploaded the file the first time
The Java classes that specify the user objects are declared as following:
#NodeEntity
public abstract class BaseUserEntity {
#GeneratedValue
#Id
private Long id;
...
}
public class UserEntity extends BaseUserEntity {
#Id
private String email;
private String passwordHash;
...
}
And the entity for the file information looks like this:
#NodeEntity
public class FileHashEntity {
#DateLong
private Date creationTime;
#Id
private String sha256;
...
private long size;
#Relationship(type = "UPLOADED_BY", direction = Relationship.OUTGOING)
private UserEntity uploader;
...
}
If I try to store the FileHashEntity I receive an error due to the complex object property (UserEntity):
public interface FileHashRepository extends Neo4jRepository<FileHashEntity, String> {
#Query(value = "merge (n:FileHashEntity {sha256: {0}}) on create set n = {1} return n")
FileHashEntity storeIfNotExists(String sha256, FileHashEntity entity);
...
}
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Property values can only be of primitive types or arrays thereof
at org.neo4j.driver.internal.net.SocketResponseHandler.handleFailureMessage(SocketResponseHandler.java:76)
But the Spring documentation states that this should be possible even without explicit #Relationship annotation (see link above). I even tried to replace the declaration type UserEntity by BaseUserEntity. What's wrong?

Datanucleus enhancer error: no objectid-class

I have the below domain model class
#Entity #Access(AccessType.FIELD)
public class MyBean {
#Id #GeneratedValue
private Long id;
...
#Transient
public String getOther() {
...
}
}
Running DataNucleus Enhancer gives the following error:
Class MyBean has application-identity and no objectid-class specified yet has 0 primary key fields. Unable to use SingleFieldIdentity.
Why?
It seems that the problem is the #Transient annotation on the method. Removing it solved the issue.
Still, in this case, taking into account the #Access and #Id annotation on a field, the #Transient annotation should be ignored. Or, preferably, the error message should be improved.

#Entity not recognizing the #Id in a #MappedSuperclass

I'm attempting to create a base class for a set of entities to reduce coding effort and duplication. My thought is that the base class has the common meta-data fields, and the child classes deal with their unique attributes.
My base class:
#MappedSuperclass
public abstract class FinanceEntityBean {
protected Long id;
#Version
private long version;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
The first entity:
#Entity
#Table(name = "tag")
public class Tag extends FinanceEntityBean {
}
I've written tests using this code to do CRUD functions on the Tag entity, and they are all working fine.
My question is - why does Eclipse (Indigo) insist that Tag has an error:
The entity has no primary key attribute defined
I've changed that to a warning for now so my code will compile, but I'm curious why Eclipse isn't happy, and if I've misunderstood something.
Is this valid JPA 2.0 code? Hibernate 4.1.5 is my JPA provider.
When using mixed access you have to specify the access type. See Eclipse Dali bug 323527 for giving a better validation error when both fields and properties are annotated.
Option 1 : Annotate the getVersion() method instead, only properties are annotated.
Option 2 : Specify mixed access type as follows:
#MappedSuperclass
#Access(AccessType.PROPERTY)
public abstract class FinanceEntityBean {
protected Long id;
#Version
#Access(AccessType.FIELD)
private long version;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
}
If FinanceEntityBean is defined in a different Eclipse project from Tag, you may be suffering from the Dali bug "No primary key attribute in other plug-in project".
The workaround is to list FinanceEntityBean in the persistence.xml file associated with Tag.
I am fairly certain those are valid mappings.
The JPA 2.0 spec provides this example when talking about MappedSuperClasses (section 2.11.2):
#MappedSuperclass
public class Employee {
#Id protected Integer empId;
#Version protected Integer version;
#ManyToOne #JoinColumn(name="ADDR") protected Address address;
public Integer getEmpId() { ... }
public void setEmpId(Integer id) { ... }
public Address getAddress() { ... }
public void setAddress(Address addr) { ... }
}
// Default table is FTEMPLOYEE table
#Entity public class FTEmployee extends Employee {
// Inherited empId field mapped to FTEMPLOYEE.EMPID
// Inherited version field mapped to FTEMPLOYEE.VERSION
// Inherited address field mapped to FTEMPLOYEE.ADDR fk
// Defaults to FTEMPLOYEE.SALARY protected Integer salary;
public FTEmployee() {}
public Integer getSalary() { ... }
public void setSalary(Integer salary) { ... }
}
I had the same problem, but for a different reason, but I didn't realize it. In further research I found that in my case I had the MappedSuperclass in a different jar. According to User Gas https://stackoverflow.com/users/3701228/gas:
"According to JPA spec, if you have jpa classes in separate jar you should add it to the persistence.xml (I don't know, if Hibernate requires that, but you can give it a try). Try to add following entry to your persistence.xml entity.jar"
He references what is the right path to refer a jar file in jpa persistence.xml in a web app? as a description on how to do this.
I know this is late, but it is still an issue. Thank you #Kemoda stating in a comment to the question, this can be turned off in Eclipse preferences.
Easiest way to "correct" this is to go set preference as you see fit for your environment. I like "Warning" because in cases where the entity does not have a primary key is an error situation.
JPA
Errors/Warnings
Type
Entity has no primary key: [Error|Warning|Info|Ignore]

#OneToOne annotation within composite key class is not working

Maybe somebody can clarify what is wrong with the code below. When I create one-to-one association within embedded class (it is composite primary key) like in the code below:
#Entity
public class Test {
#EmbeddedId
private TestId id;
#Embeddable
public static class TestId implements Serializable {
private static final long serialVersionUID = 1950072763330622759L;
#OneToOne(optional = false)
#JoinColumn(name = "linkedTable_id")
private LinkedTable linkedTable;
}
..........
}
I get the following stack trace:
--------------------------------------------
Caused by: java.lang.NullPointerException
at org.hibernate.cfg.AnnotationBinder.bindOneToOne(AnnotationBinder.java:1867)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1286)
at org.hibernate.cfg.AnnotationBinder.fillComponent(AnnotationBinder.java:1662)
at org.hibernate.cfg.AnnotationBinder.bindId(AnnotationBinder.java:1695)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1171)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:706)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:452)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:268)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1121)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1211)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:154)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:847)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:178)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:235)
... 26 more
What is interesting why the sample above works if I change association type to many-to-one and doesn't work with one-to-one?
I wasn't aware this was possible but, according to the Hibernate Annotation reference documentation, it is (this is Hibernate specific though):
2.2.3.2.1. #EmbeddedId property
(...)
While not supported in JPA, Hibernate
lets you place your association
directly in the embedded id component
(instead of having to use the
#MapsId annotation).
#Entity
class Customer {
#EmbeddedId CustomerId id;
boolean preferredCustomer;
}
#Embeddable
class CustomerId implements Serializable {
#OneToOne
#JoinColumns({
#JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
#JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
})
User user;
String customerNumber;
}
#Entity
class User {
#EmbeddedId UserId id;
Integer age;
}
#Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
And with the code you provided, the following snippet just works for me:
LinkedTable linkedTable = new LinkedTable();
linkedTable.setId(1l);
session.persist(linkedTable);
session.flush();
Test.TestId testId = new Test.TestId();
testId.setLinkedTable(linkedTable);
Test test = new Test();
test.setId(testId);
session.persist(test);
session.flush();
Tested with Hibernate EM 3.4.0.GA, Hibernate Annotations 3.4.0.GA and Hibernate Core 3.3.0.SP1.
If it doesn't work for you, can you provide a bit more code allowing to reproduce the problem?

Categories

Resources