datanucleus / datanucleus-api-jpa Goto Github PK
View Code? Open in Web Editor NEWSupport for DataNucleus persistence using the JPA API (JSR0220, JSR0317, JSR0338)
Support for DataNucleus persistence using the JPA API (JSR0220, JSR0317, JSR0338)
Refer to property "datanucleus.schema.autoCreateSchema", which is now implemented to create the schema just before creating whatever table needs creating. This is likely slightly different from the JPA requirement, but serves as a starting point
Hello.
We use datanucleus 4.2.5 jpa with jcache (on appengine).
Recently we face with a problem of updating relational object in our entities with enabled 2nd level cache (jcache in our case).
We have the relation OneToOne for our entities: User - Address. Both of them have versioned field of Long type. During update we retrieve the User entity which has OneToOne Address entity which is fetched eagerly (default value for OneToOne mapping).
After updating fields of these entities on saving User we get the following exception:
"Caused by: org.datanucleus.exceptions.NucleusException: Object with id "1" in table address has no version set on the object in memory and you want to update it!! Please report this bug to the developers of DataNucleus with a way of reproducing it"
(The version value is set in database.)
After some investigation we found that the problem relates to the class StateManagerImpl the "transactionalVersion" field is not set for eagerly fetched entities.
For User entity "transactionalVersion" is set as expected, but for Address entity - no. So we got the error at the line: 384 of UpdateRequest class in this code:
"if (currentVersion == null)
{
// Somehow the version is not set on this object (not read in ?) so report the bug
String msg = Localiser.msg("052201", op.getInternalObjectId(), table);
NucleusLogger.PERSISTENCE.error(msg);
throw new NucleusException(msg);
}
"
We also found that if we change the fetching type = lazy - the problem disappears.
If we use Criteria and do
root.join("b.c");
this tries to create a join
DN_THIS.c and this doesn't exist.
This will mean that native query will equate to CQL for Cassandra etc, rather than just being ok for RDBMS.
See #26
The JPA spec says that we should throw IllegalStateException if calling methods on a query when the EntityManager is closed, and we don't currently. Also when closing the EntityManager there are some variables to be nulled.
If we do a Criteria query that joins across 2 relations and don't put aliases on the joins then we get invalid JPQL.
For example
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery crit = builder.createQuery();
Root root = crit.from(A.class);
Join j1 = root.join("b");
// j1.alias("b");
Join j2 = j1.join("c");
// j2.alias("c");
This resolves to JPQL of
SELECT DN_THIS FROM mydomain.model.A DN_THIS JOIN DN_THIS.b JOIN null.c
but if we add the aliases then it is fine
See #36
We should allow a user to specify AttributeOverrides against a Map field where the value is embedded.
See #27
Works fine when using annotations, but when using orm.xml only we have no default entityName and so a query can fail to find the class
Here are domains classes:
@MappedSuperclass
public abstract class BaseEntity<ID extends Serializable> {
@Id
@Column(name = ID)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQ_GEN)
@SequenceGenerator(name = SEQ_GEN, allocationSize = 1)
private ID id;
...
}
@Entity
public class Note extends BaseEntity<Long> {
}
Getting exception:
Caused by: java.lang.IllegalArgumentException: PK member is not of specified type (java.lang.Long). Should be java.io.Serializable
at org.datanucleus.api.jpa.metamodel.IdentifiableTypeImpl.getId(IdentifiableTypeImpl.java:102)
at org.datanucleus.api.jpa.metamodel.IdentifiableTypeImpl.getId(IdentifiableTypeImpl.java:79)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:249)
IdentifiableTypeImpl.java
public <Y> SingularAttribute<? super X, Y> getId(Class<Y> cls)
{
...
int pkPosition = cmd.getPKMemberPositions()[0];
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkPosition);
// *BUG*: We come here with supertype,
// thus, it should be mmd.getType().isAssignableFrom(cls)
if (cls.isAssignableFrom(mmd.getType()))
{
// User passed in the type of the field
SingularAttribute attr = (SingularAttribute) attributes.get(mmd.getName());
if (attr == null)
{
IdentifiableType supertype = getSupertype();
if (supertype != null)
{
// Relay to the supertype
return supertype.getId(cls);
}
}
return attr;
}
...
}
The following shows a project that contains various entity mappings but enhancing it fails because a duplicate attribute is said to be encountered. I suppose this is a problem with detecting bridge methods?
jpa-treat-variations.zip
See #35
Is LockModeType.OPTIMISTIC_FORCE_INCREMENT
supposed to work?
We have added the necessary API for JPA Criteria to support nulls first/last (javax.persistence 2.1.3). Support it in the API plugin
See #32
OPTIMISTIC_FORCE_INCREMENT doesn't work, please see test case attached which can be run with the following command.
mvn test
Raised by Peter Kriens.
There is an unnecessary dependency in Datanucleus on Blueprint. Since it is trivial to to register a service in a BundleActivator, which does not introduce dependencies, it would be much nicer if the Blueprint dependency was removed.
Marked in the JPA spec as non-portable if setting the result type to Tuple, but we should support it.
The static metamodel generator of Datanucleus 5 generates null for byte[] properties.
Testcase:
https://github.com/Mobe91/test-jpa/tree/metamodel-bug
If we see
@convert(converter=...)
Collection myColl;
we assume the converter is for the SomeType currently, but ought to check and apply to the whole field if not appropriate for the field
https://github.com/mkolesnikov/datanucleus-test-jap
See org.datanucleus.test.IdentifiableTypeImplTest.testGetVersion()
@MappedSuperclass
public abstract class BaseEntity {
...
@Version
private Timestamp version;
...
}
@Entity
public class Person extends BaseEntity {
...
}
Exctract from IdentifiableTypeImpl
(see inline comments)
public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> cls)
{
// BUG : cmd.getVersionMetaData() is always null in our case,
// cmd.getVersionMetaDataForClass().getFieldName() should be used instead
String verFieldName = (cmd.getVersionMetaData() != null ? cmd.getVersionMetaData().getFieldName() : null);
if (verFieldName != null)
{
AbstractMemberMetaData verMmd = cmd.getMetaDataForMember(verFieldName);
if (cls.isAssignableFrom(verMmd.getType()))
{
SingularAttribute attr = (SingularAttribute) attributes.get(verFieldName);
if (attr == null)
{
IdentifiableType supertype = getSupertype();
if (supertype != null)
{
// BUG: copy-pasted code. It should call supertype.getVersion(cls);
// Relay to the supertype
return supertype.getId(cls);
}
}
return attr;
}
throw new IllegalArgumentException("Version is not of specified type (" + cls.getName() + "). Should be " + verMmd.getTypeName());
}
return null;
}
We currently rely on the user to add the discriminator manually.
See #47.
Should create !(xxx IN (...))
The JPA 2.1 spec says
public void addAttributeNodes(Attribute<T, ?>... attribute);
but should be
public void addAttributeNodes(Attribute... attribute);
We could decide to just provide our own JPA API jar and datanucleus-api-jpa.jar to go with it. Targetting this for v5.0 so we have a clean change over
When we define Entity listeners in MetaData JPOX needs to support identifying the methods when populating the EventListenerMetaData. This also needs to support inheritance where the superclass is specified using <mapped-superclass>
We currently have to mark a 1-N relation as
@OneToMany
@extensions({@extension(key="relation-discriminator-column", value="ADDRESS_TYPE"),
@extension(key="relation-discriminator-pk", value="true"),
@extension(key="relation-discriminator-value", value="work")}
Collection
to mark it as having a distinguisher column and be shared. It would be simpler to specify
@OneToMany
@SharedRelation(column="ADDRESS_TYPE", primaryKey=true, value="work")
Collection
We currently don't use the "name" attribute of these annotations correctly.
See #30
I encountered a metamodel issue when retrieving the persistentAttributeType of an embeddable property. The persistentAttributeType evaluates to ONE_TO_ONE
while it should actually evaluate to EMBEDDED
. I also tested the behavior with Hibernate and EclipseLink which both yielded the expected result. The issue occurs with both Datanucleus 4 and Datanucleus 5. The supplied testcase uses Datanucleus 4:
https://github.com/Mobe91/test-jpa
So the user can do the following at class-level
@readonly
public class MyClass {...}
to equate to
@extension(key="read-only", value="true")
public class MyClass {...}
or the following at member-level
public class MyClass
{
@readonly
String myReadOnlyField;
}
Should check the type of the collection element or map value and use that for its checks.
Should create !(xxx IN (...))
Refer to core issue 19
After the tickets #27 #29 were fixed the NPE occurs when IdentifiableTypeImpl.getSupertype is invoked:
java.lang.NullPointerException
at org.datanucleus.api.jpa.metamodel.IdentifiableTypeImpl.getSupertype(IdentifiableTypeImpl.java:157)
at org.datanucleus.api.jpa.metamodel.IdentifiableTypeImpl.getVersion(IdentifiableTypeImpl.java:188)
Because of this Spring Data JPA does not work:
[INFO] java.lang.NullPointerException
[INFO] at org.datanucleus.api.jpa.metamodel.IdentifiableTypeImpl.getSupertype(IdentifiableTypeImpl.java:157)
[INFO] at org.datanucleus.api.jpa.metamodel.IdentifiableTypeImpl.getVersion(IdentifiableTypeImpl.java:188)
[INFO] at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.findVersionAttribute(JpaMetamodelEntityInformation.java:107)
[INFO] at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:83)
[INFO] at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:67)
[INFO] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:152)
[INFO] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:99)
[INFO] at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:81)
[INFO] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:199)
[INFO] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:266)
[INFO] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:252)
[INFO] at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
datanucleus-api-jpa version: 4.1.11
datanucleus-core version: 4.1.12
Here is a test case:
https://github.com/ayakovlevgh/test-jpa/tree/4.1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.