[JPA_SPEC-121] Oracle JPA tutorial contains INCORRECT use of static metamodel Created: 18/Nov/15  Updated: 18/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: neilstockton Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See this page
https://docs.oracle.com/javaee/6/tutorial/doc/gjiup.html

It says

"The following code snippet shows how to obtain the Pet entity’s metamodel class by calling Root<T>.getModel:
EntityManager em = ...;
Root<Pet> pet = cq.from(Pet.class);
EntityType<Pet> Pet_ = pet.getModel();"

Pet_ is the CANONICAL static metamodel and does NOT implement EntityType. This is utterly wrong. You get Pet_ by statically referring to it, and it is generated by an annotation processor.

The same tutorial even has
@Static Metamodel(Pet.class)
public class Pet_

{ public static volatile SingularAttribute<Pet, Long> id; public static volatile SingularAttribute<Pet, String> name; public static volatile SingularAttribute<Pet, String> color; public static volatile SetAttribute<Pet, Owner> owners; }

so it says Pet_ does not implement EntityType (and indeed is nothing to do with it).

This should be FIXED ASAP, or you will utterly confuse people






[JPA_SPEC-117] Allow TREAT with identification variable in JOIN Created: 27/Sep/15  Updated: 01/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Imagine the following example.

@Entity
public class B {
...
}

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class BaseA {
...
}

@Entity
@DiscriminatorValue("A1")
public class A1 extends BaseA {
@ManyToOne
private B a1B;
}

@Entity
@DiscriminatorValue("A2")
public class A2 extends BaseA {
@ManyToOne
private B a2B;
}

When querying for BaseA the only possible way to join a1B or a2B are to do cross joins with the subclass entity types. This is inefficient and unreadable. By allowing TREAT in the join_association_path_expression to accept just an identification_variable and after the treat followed by either collection_valued_field or single_valued_object_field, the persistence provider could implement this kind of query much more efficient. An example query would look like

SELECT a FROM BaseA a 
LEFT JOIN FETCH TREAT(a AS A1).a1B 
LEFT JOIN FETCH TREAT(a AS A2).a2B

The new BNF would be

join_association_path_expression ::=
join_collection_valued_path_expression |
join_single_valued_path_expression |
TREAT(join_collection_valued_path_expression AS subtype) |
TREAT(join_single_valued_path_expression AS subtype) |
TREAT(identification_variable AS subtype).{single_valued_embeddable_object_field.}*collection_valued_field |
TREAT(identification_variable AS subtype).{single_valued_embeddable_object_field.}*single_valued_object_field


 Comments   
Comment by c.beikov [ 01/Nov/15 ]

If this is added, it only makes sense to also allow nesting TREAT to make the following possible

@Entity
public class C {
...
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class B {
...
}

@Entity
public class B1 extends B {
private C b1C;
}

@Entity
public class B2 extends B {
private C b2C;
}

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class BaseA {
...
}

@Entity
@DiscriminatorValue("A1")
public class A1 extends BaseA {
@ManyToOne
private B a1B;
}

@Entity
@DiscriminatorValue("A2")
public class A2 extends BaseA {
@ManyToOne
private B a2B;
}
SELECT a FROM BaseA a 
LEFT JOIN FETCH TREAT(TREAT(a AS A1).a1B AS B1).b1C
LEFT JOIN FETCH TREAT(TREAT(a AS A2).a2B AS B2).b2C

So the new BNF would be something like the following

join_association_path_expression ::=
join_collection_valued_path_expression |
join_single_valued_path_expression |
TREAT(join_collection_valued_path_expression AS subtype) |
TREAT(join_single_valued_path_expression AS subtype) |
TREAT(identification_variable AS subtype).{single_valued_embeddable_object_field.}*collection_valued_field |
TREAT(identification_variable AS subtype).{single_valued_embeddable_object_field.}*single_valued_object_field |
TREAT(TREAT(identification_variable AS subtype).{single_valued_embeddable_object_field.}*collection_valued_field AS subtype) |
TREAT(TREAT(identification_variable AS subtype).{single_valued_embeddable_object_field.}*single_valued_object_field AS subtype)




[JPA_SPEC-43] Allow type level annotations to be used as meta-annotations Created: 17/Jan/13  Updated: 01/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: Lukas Jungmann
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by JPA_SPEC-98 Improve Entity Graph annotations Resolved
Tags: JavaEE, metatypes

 Description   

I repeatedly find myself annotating my JPA entities with the very same set of annotations:

@Entity
@EntityListeners(AuditingEntityListener.class)
class Person {

}

If both @Entity and @EntityListener were allowed to be used as meta-annotations I could collapse them into:

@Target(TYPE)
@Retention(RUNTIME)
@Entity
@EntityListeners(AuditingEntityListener.class)
@interface @AuditedEntity {

}

Resulting in:

@AuditedEntity
class Person {

}

This is in line with the meta-annotation handling CDI exposes to introduce annotation with richer semantics in annotation code. The following changes would be required.

  • Add ElementType.ANNOTATION_TYPE to the relevant annotations
  • Specify that persistence providers have to evaluate the annotations from the meta-level as well using the first one found, so that locally defined annotations would be considered first.


 Comments   
Comment by ldemichiel [ 18/Jan/13 ]

Support for this functionality is on our roadmap for Java EE 8. We should revisit this issue at that time.

Comment by Lukas Jungmann [ 23/Sep/15 ]

Why do you think that ElementType.ANNOTATION_TYPE should be added to relevant annotations? Annotations having ElementType.TYPE are already allowed to be used on annotation types.

Comment by Oliver Gierke [ 31/Oct/15 ]

O.o - you're completely right. I'm quite ashamed I wasn't aware of that . There's still tow aspects though:

  • it would be cool if all annotations were usable as meta-annotations (might need to change the ticket description). The ones currently to be used with methods or fields only can't be used this way right now.
  • I think it deserves a dedicated section/sentence on the meta-annotation usage in the spec to make sure all implementors actually support it
Comment by Oliver Gierke [ 31/Oct/15 ]

I've just checked Hibernate 4.3.11 and when tying to create a composed annotation with @Entity as meta-annotation, it considers the annotation type (@AuditedEntity from my original example) as entity type and complains about a missing identifier. So it seems at least Hibernate doesn't consider meta-annotations the way the should right now.

Comment by Lukas Jungmann [ 31/Oct/15 ]

check RI / EclipseLink nightly from master (2.7), it should be supported there already

as for the section in the spec - right, it has to be added and it should define which types are allowed to be used on meta annotations I'll share the 'draft' for this section either within this ticket or through users mailing list.

Comment by Oliver Gierke [ 01/Nov/15 ]

Thanks for that, Lucas. Are there any consumable nightly builds of EclipseLink 2.7 somewhere?

Comment by Lukas Jungmann [ 01/Nov/15 ]

sure, https://www.eclipse.org/eclipselink/downloads/nightly.php if you prefer maven then see https://wiki.eclipse.org/EclipseLink/Maven for the repo setup

Comment by Lukas Jungmann [ 01/Nov/15 ]

btw: JPA_SPEC-109 has been implemented in RI as well





[JPA_SPEC-13] Support use of EntityResult within ConstructorResult Created: 05/Dec/11  Updated: 04/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: ldemichiel Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: RFE

 Description   

Support use of EntityResult within ConstructorResult for result type mapping of native queries.






[JPA_SPEC-12] Addition of preCreate/postCreate callbacks for EntityManagerFactory Created: 05/Dec/11  Updated: 15/Apr/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: ldemichiel Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: RFE

 Description   

This would be useful hook for creation and/or modification of named queries.



 Comments   
Comment by ldemichiel [ 05/Dec/11 ]

We don't currently have a well-defined initialization sequence, and the EMF may be created by the container before application code gets to execute. However, a startup singleton EJB's postConstruct could be used for adding named queries, or a servlet init method.

Comment by c.beikov [ 15/Apr/14 ]

I have the feeling that JPA_SPEC-23 is also kind of related to this issue if a preCreate callback allowed for mutation of the meta- and physical model.





[JPA_SPEC-9] Dynamic specification of result type mappings for native queries Created: 05/Dec/11  Updated: 04/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: ldemichiel Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

API for specifying result type mappings. Currently this is handled through metadata, and is therefore static






[JPA_SPEC-3] Allow components other than stateful sessions beans to initiate container-managed extended persistence contexts Created: 05/Dec/11  Updated: 05/Jul/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: ldemichiel Assignee: ldemichiel
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It might be useful to support the use of container-managed extended persistence contexts in singleton session beans and/or application-scoped or conversation-scoped CDI components.



 Comments   
Comment by donatasc [ 05/Feb/13 ]

+100

IMHO this was a huge miss in Java EE 6. Even though CDI introduced conversation scope, injection/creation of extended persistence context EM was not mentioned at all. EJB spec is also silent about extended PC, what caused me to post message like this to JPA mailing list:
http://java.net/projects/jpa-spec/lists/users/archive/2013-01/message/51

In general, extended persistence context is largely under-specified in regards to integration between CDI/EJB/JPA.

Comment by kostd [ 04/Jul/16 ]

In fact it is working now. I think before (on java 6) its already worked, but not sure.

Checked in environments:

Environment1: java7u80, wildfly 8.2.0.Final, wildfly-jpa-8.2.0.Final, hibernate 4.3.7.Final, weld 2.2.6.Final, wildfly-ejb3 8.2.0.Final, extended-persistence inheritance = DEEP(default)
Environment2: java8u77, wildfly 10.0.0.Final, wildfly-jpa-10.0.0.Final, hibernate 5.0.7.Final, weld 2.3.2.Final, wildfly-ejb3 10.0.0.Final, extended-persistence inheritance = DEEP(default)

have:


@ConversationScoped
public class CDIBean1 implements Serializable{

	private static final long serialVersionUID = 1L;

	@Inject
	CDIBean2 cdibean2;
	
	@Inject
	StatelessBean statelessBean;
	
	public void doSomthing(){
		
		cdibean2.doSomthing();
		statelessBean.doSomthing();
		
	}
}
...

@ConversationScoped
public class CDIBean2  implements Serializable{

	private static final long serialVersionUID = 1L;

	@PersistenceContext(type=PersistenceContextType.EXTENDED, synchronization=SynchronizationType.UNSYNCHRONIZED)
	EntityManager em;
	
	
	public void doSomthing(){
		
		List<StreetType> streets  = em.createQuery(" from StreetType").getResultList();
		
		SessionImpl session = (SessionImpl) em.unwrap(SessionImpl.class);
		System.out.println("there are " + session.getPersistenceContext().getNumberOfManagedEntities() + " entities in XPC after initiation");
	}
}
...

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class StatelessBean {
	
	@PersistenceContext
	EntityManager em;
	
	public void doSomthing(){
		
		SessionImpl session = (SessionImpl) em.unwrap(SessionImpl.class);
		
		System.out.println("there are " + session.getPersistenceContext().getNumberOfManagedEntities() + " entities in transaction-scoped persistence context");
		
	}

}

after call CDIBean1#doSomething() can see that XPC was initiated in CDIBean2#doSomething() and propogated as TxPC in stateless EJB. Both output strings show same managed object count in persistence context.

I vote to reviewing of "7.6.3 Container-managed Extended Persistence Context" in JPA-SPEC 2.1:

A container-managed extended persistence context can only be initiated within the scope of a stateful
session bean. It exists from the point at which the stateful session bean that declares a dependency on an
entity manager of type PersistenceContextType.EXTENDEDis created, and is said to be bound
to the stateful session bean.

this is not truth truth is:

A container-managed extended persistence context can only be initiated within the scope of a stateful
session bean or CDI bean. It exists from the point at which the bean that declares a dependency on an
entity manager of type PersistenceContextType.EXTENDED is created, and is said to be bound
to that (stateful or CDI) bean.





[JPA_SPEC-139] Provide constants for properties Created: 03/Dec/16  Updated: 03/Dec/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Task Priority: Major
Reporter: ggam Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There are a lot of available properties, each one applicable to specific scenarios:

  • Persistence Unit level properties (persistence.xml).
  • Entity Manager level properties (EntityManager#setProperty()).
  • Query hints.

Those properties are scattered trough the spec and it's difficult to find all of them and to know which one applies to which scenario.

A simple yet very handful addition would be a class that groups all the properties and specifies its applicability in its JavaDoc.

Hibernate already does something like this: https://github.com/hibernate/hibernate-orm/blob/0a2a5c622e3eb30724e80bc8661c0ac55ebfb2be/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java






[JPA_SPEC-138] Metamodel should expose methods to determine *all* JPA-handled types Created: 04/Nov/16  Updated: 05/Nov/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JPA has always had a Metamodel API to find out about managed entities, managed superclasses and embeddable type. With the introduction of attribute converters, other types get under control of the JPA provider, too. E.g. depending on whether an `AttributeConverter` is registered for it or not, a `LocalDateTime` (or any other type) could be effectively become a JPA understood "primitive" type.

Currently there's no way for clients to use the Metamodel API to find out about that fact that there certain types are JPA-understood ones. It'd be great if that could be found out.



 Comments   
Comment by neilstockton [ 05/Nov/16 ]

Related to comments on https://java.net/jira/browse/JPA_SPEC-35 and should be a way of seeing what types are supported by the in-use JPA provider (since if you just took the list from the JPA spec, you'd not get very far).





[JPA_SPEC-131] correct inaccuracies in JPA_SPEC 2.1 *7.6.4 Persistence Context Propagation* Created: 06/Jul/16  Updated: 31/Aug/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.2, 2.1.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: kostd Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: cdi, persistence-context, propagation, sfsb, slsb
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Environment1: java7u80, wildfly 8.2.0.Final, wildfly-jpa-8.2.0.Final, hibernate 4.3.7.Final, weld 2.2.6.Final, wildfly-ejb3 8.2.0.Final, extended-persistence inheritance = DEEP(default)

Environment2: java8u77, wildfly 10.0.0.Final, wildfly-jpa-10.0.0.Final, hibernate 5.0.7.Final, weld 2.3.2.Final, wildfly-ejb3 10.0.0.Final, extended-persistence inheritance = DEEP(default)



 Comments   
Comment by kostd [ 06/Jul/16 ]

1. 7.6.4.1 Requirements for Persistence Context Propagation

If an entity manager is then invoked from within the component:
• Invocation of an entity manager defined with PersistenceContextType.TRANSACTION will result in use of a new persistence context (as described
in section 7.6.2).

actually:

Invocation of an entity manager defined with PersistenceContextType.TRANSACTION will result in use of the existing persistence context, associated with current transaction,
if one exists, or a new persistence context (as described in section 7.6.2).

2. 7.6.3 Container-managed Extended Persistence Context

A container-managed extended persistence context can only be initiated within the scope of a stateful
session bean.

actually:

A container-managed extended persistence context can only be initiated within the scope of a stateful session bean or CDI non @Dependent bean. Dependent CDI beans cannot initiate extended persistence context, because no injected instance of one bean is ever shared between multiple injection points. Stateless beans cannot initiate extended persistence context because instance`s identity of beans not guaranteed.

Comment by kostd [ 31/Aug/16 ]

A container-managed extended persistence context can only be initiated within the scope of a stateful session bean or CDI non @Dependent bean

I lied
in fact CDI bean can initiate only transaction-scoped persistence context (hardcoded in weld implementation)





[JPA_SPEC-130] Allow defining null handling for ORDER BY expressions in JPQL and the Criteria API Created: 06/Jul/16  Updated: 01/Dec/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, neither JPQL nor the Criteria API allow defining how to handle null values in ORDER BY expressions. All major persistence providers support those clauses though, which makes it sort of usable through JPQL (as the provider might allow the custom extensions) but not through the Criteria API.



 Comments   
Comment by neilstockton [ 01/Dec/16 ]

Dup of https://java.net/jira/browse/JPA_SPEC-76 no?





[JPA_SPEC-129] Missing @MapKeyAttributeOverride Created: 27/Jun/16  Updated: 27/Jun/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: gaurav.gupta Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

@AttributeOverride annotation cannot be used , if both key and value are Embeddable as defined in following case :

@ElementCollection
@AttributeOverride(name = "attribute_1", column = @Column(name = "ATTRIBUTE_1_OV"))
@AttributeOverride(name = "attribute_2", column = @Column(name = "ATTRIBUTE_2_OV"))
private Map<Embeddable_1, Embeddable_2> embeddableAttribte;

So it should be look like to override map key attribute :

@ElementCollection
@MapKeyAttributeOverride(name = "attribute_1", column = @Column(name = "ATTRIBUTE_1_OV"))
@AttributeOverride(name = "attribute_2", column = @Column(name = "ATTRIBUTE_2_OV"))
private Map<Embeddable_1, Embeddable_2> embeddableAttribte;






[JPA_SPEC-114] Allow full configuration of EntityManagerFactory without persistence.xml Created: 28/Aug/15  Updated: 09/Apr/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: moodysalem Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I'd like to be able to register classes, set a persistence provider, and also add packages to scan (bonus).

In addition, I don't think persistence unit name should be required-at least an exception shouldn't be thrown if no persistence.xml is found or no persistence unit with the name is found.

My end-goal is an hk2 factory, in the JAX-RS context (https://jersey.java.net/documentation/latest/ioc.html) that can be instantiated with a JDBC url, username, password, and package names to scan, and then bound to EntityManager for injection. Without the ability to configure the classes that an entity manager factory loads, this is difficult (requires a persistence xml in the project that uses the factory)



 Comments   
Comment by Xavier Dury [ 10/Dec/15 ]

Can't you just create your own javax.persistence.spi.PersistenceUnitInfo and do something like this to begin with? (no package scanning)

for (PersistenceProvider provider : PersistenceProviderResolverHolder.getPersistenceProviderResolver().getPersistenceProviders()) {
	return provider.createContainerEntityManagerFactory(persistenceUnifInfo, properties);
}
Comment by OndrejM [ 09/Apr/16 ]

The above piece of code is great stuff, it's a pity almost noone knows that something like this is possible.
Though, I'd welcome more declarative way that makes it possible to combine with @PersistenceUnit, which everybody knows how to use.

Something like having a CDI producer with methods marked with @PersistenceUnitDefinition qualifier:

public class PersisteneConfig {
  @Produces
  @PersistenceUnitDefinition(name = "puMain")
  public PersistenceUnitInfo puMainInfo() {
    return persistenceUnitInfo;
  }

  @Produces
  @PersistenceUnitDefinition(name = "puMain")
  public Map puMainProperties() {
    return properties;
  }
}

If CDI producer would be too late in the lifecycle, or dependency on CDI is not convenient, than some kind of listener executed soon enough in the lifecycle.





[JPA_SPEC-113] Allow the use of @GeneratedValue even if column is not primary key. Created: 19/Aug/15  Updated: 12/Apr/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: paranoiabla Assignee: ldemichiel
Resolution: Unresolved Votes: 10
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello,

My scenario is the following - I have a @MappedSuperclass which defines a field pk (which is generated value with a custom generic generator) but I also have an entity called Order with a property code. I have created a custom generic generator which calculates on the server what the order code must be, but even though I have specified it as this:

    @Column(name = "code", nullable = false)
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid")
    private String code;

This generator is never called. I checked the javadoc and there explicitly says that the @GeneratedValue is used together with @Id. My proposal is to allow it to be used on columns that are not @Id.



 Comments   
Comment by j0ke [ 05/Apr/16 ]

@GenericGenerator is hibernate specific annotation, however it will be nice to have similar way in JPA ( or GenericType (again from hibernate), maybe we should submit a new request for that ?

However I vote that will be nice if this works :

//@Id without ID since we have a different PK in this entity already which is the @Id .. likepk or something.
@GeneratedValue(strategy=GenerationType.TABLE, generator="orderGenerator")
@TableGenerator(
    name="orderGenerator",
    table="GENERATOR_TABLE",
    pkColumnName = "key",
    valueColumnName = "next",
    pkColumnValue="order_number",
    allocationSize=30)
private String orderNumber;
Comment by neilstockton [ 05/Apr/16 ]

Since this issue is about allowing GeratedValue to be used on non-PK fields then yes you most certainly have to create that on a separate issue. And while doing so, state what you want it for, because just saying "I want something like this Hibernate annotation" is saying absolutely nothing about why you think something should become a standard

Comment by j0ke [ 05/Apr/16 ]

I Agree but for now I will be very happy if the @GeneratedValue does not require @Id.
Otherwise why we have 2 annotations, we can have an attribute in the Id saying "strategy" and "generator" as optional, having it like this 2 annotations that kinda work magically only together looks bad.

About the GenericGenerator and GeneratorType (both from Hibernate) we indeed should discuss in separate issue and of course I will not say "because Hibernate have them", you can trust me I am an engineer !

Nayden

Comment by ngagov [ 10/Apr/16 ]

It will be good if we could generate values for non- @Id columns via standard JPA annotations, simply because not only the @Id columns might require custom value generation.
May be in JPA we could have separate annotations just like @GeneratorType and @ValueGenerationType in Hibernate, which allows generation of values for non-@Id columns.

Comment by neilstockton [ 12/Apr/16 ]

I don't see why you need "GeneratorType" or "ValueGenerationType" annotations (whatever they do) ... you simply need an implementation to support @GeneratedValue on the field; no need to complicate things for no defined benefit. If you think some other annotation is needed, then state what you think that is adding and why it is needed

Comment by j0ke [ 12/Apr/16 ]

@neilstockton yes indeed @GeneratedValue can be supported by some implementation but why should it be just supported by implementation instead of support in the spec ?
About the "other" annotation you may want a non numeric PK generation. For example for shippings or orders it doesn't make sense to have your order id is 12012 or your shipping is 23123321 it make sense to have a class/strategy that can provide the PK/ID value so you may have an ID like

${MERCHANTID}-${CLIENTID}-${ORDERNumberPerThisClient}

and so on as PK not just Sequence, auto increment or table with PK nextvals.

Comment by neilstockton [ 12/Apr/16 ]

My comment was to the previous poster (ngagov), and nowhere have I said @GeneratedValue should _not_ be on non-PK fields ... in fact I said I totally support that being in the standard (and I already use that in the implementation I use which does support it on non-PKs)!

I asked what are these other annotations, and why should the standard have them? I repeat the point i made to you earlier (which you are supposed to raise in a separate issue) ... if you are going to PROPOSE something, then kindly explain WHAT role it performs. If you want non-numeric PK generation, like some implementations do with things like "UUID" then you can define the column type ... but there's no need of a special annotation for that, since you already have @Column!





[JPA_SPEC-127] Clearly define the behaviour when the path expression A.b is used inside or outside the WHERE clause Created: 14/Jan/16  Updated: 14/Jan/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: mauromol Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It seems like the specification leaves room for interpretation when a path expression like "A.b" is used, it represents a relationship and b is a terminal field. At least this is what EclipseLink developers state.

My specific case is described by this report:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=485414
and discussed on EclipseLink users list, see for instance:
http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg08596.html
(and the following messages).

I have a OneToOne relationship and I'm using this JPQL query:

SELECT first FROM First first WHERE first.second IS NULL

to express: give me all the First entity instances that have no Second related entity. Now, if First owns the relationship, the generated SQL query is (I'm simplifying a bit):

SELECT * FROM First t0
WHERE t0.second_id IS NULL

and brings the expected result. Instead, if the relationship is owned by Second, the generated SQL is this:

SELECT * FROM Second t1, First t0
WHERE t1.first_id IS NULL
AND t1.first_id = t0.id

which clearly fails to return the correct results, which should be given instead by:

SELECT * FROM First t0
LEFT JOIN Second t1 ON t1.first_id = t0.id
WHERE t1.first_id IS NULL

EclipseLink developers justify this by saying that in the first case an optimization is applied which does not force a join on Second (and possibly brings a wrong result then...), while in the second case this is not possible and the use of the inner join is justified by the specs, because it's a path expression that navigates from First to Second.
However, I would expect the direction of the relationship to be a mapping detail, which should not lead to different results using the exact same query on the object model, and I would expect a so simple query to give the very intuitive and natural result I was seeking for (all First instances with no corresponding Second instances).

An even more lengthy discussion, with a different use case (where the path expression is used in the select clause, rather than in the where clause) is also on:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=312146

I think a clarification on these cases would be beneficial to the spec (and to the end users, of course).






[JPA_SPEC-126] Improve exceptions to support identifying more specific exceptions such as "constraint violation" and "duplicate key" Created: 13/Jan/16  Updated: 13/Jan/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: rbygrave Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently there seems to be no easy way to check a PersistenceException to see if is a "Constraint violation" exception etc.

It would be good to have a provider agnostic and database agnostic way to as least easily identify "Constraint violation" exceptions and ideally a more specific "Unique constraint violation".

One possible approach would be to extend the exception hierarchy.






[JPA_SPEC-125] Clarify effect of entity graph on collections Created: 29/Dec/15  Updated: 29/Dec/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Harald Wellmann Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The JPA 2.1 spec does not define the effect of an entity graph on the fetch strategy or the result set of a query.

In current TCK compliant implementations, entity graphs may lead to false duplicates due to inappropriate joins.

This is related to JPA_SPEC-124.

Suppose there is a Person with two addresses and two phone numbers.

Then using an EntityGraph with addresses and phoneNumbers on the query

select p from Person where p.id = 1

may return a Person entity with 4 addresses or 4 phoneNumbers, if the implementation fetches the associations via joins.






[JPA_SPEC-124] Clarify mapping of SQL result sets to entity lists Created: 29/Dec/15  Updated: 31/Dec/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Harald Wellmann Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In the JPA 2.1 spec, I cannot find any details about the mapping of SQL result rows to the list of results returned from an entity query.

The result of the following query seems to depend on the used collection types and on the JPA implementation which is not desirable:

Example: Suppose there is a Person with two addresses and two phone numbers.

select distinct p from Person p 
left join fetch p.addresses 
left join fetch p.phoneNumbers 
where p.id = 1

The underlying SQL query will return 4 rows, and the result list is a single Person entity, where the collections may be incorrect, with 4 addresses or 4 phone numbers or even both.

The number of duplicates is influenced by the collection types:
List without @OrderColumn, List with @OrderColumn or Set.

The specification should define warnings or exceptions for cases that would lead to incorrect duplicates.



 Comments   
Comment by neilstockton [ 31/Dec/15 ]

The JPA spec doesn't go into "the underlying SQL query" and nor should it, and I'd doubt that all JPA implementations will come to the same basic SQL. Your query says return all (distinct) Person objects where p.id is 1 and make sure that these (2) collections are loaded. That is all. The implementation then decides how it wants to do it.

Duplicates should not be present ever from that query (IMHO)





[JPA_SPEC-123] Automatic previous and next references Created: 30/Nov/15  Updated: 30/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: pbenedict Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is an interesting use case that I think JPA could be enhanced to support. I have a Parent entity with a very large collection (100K+) of List<Child> entities. The list is mapped by Child and it knows its list position. However, due to my requirements, when I access a Child, I also need to navigate to the previous and next Child entities for their data too.

Existing solutions exist, but none I prefer:

  1. Navigate up from Child to Parent, grab list, do +1/-1 on the position; but this will materialize the collection inappropriately.
  2. Write myself a query to return all three objects; but this customization deviates from natural object navigation.

I prefer a navigable JPA solution because the entity manager has full knowledge of the Child's current position and its owning collection. That means JPA can take advantage of this inherent knowledge to automatically calculate the previous and next references.

Example:

public class Parent {
    @OneToMany(mappedBy = "parent")
    @OrderColumn(name = "pos")
    private List<Child> children;
}

public class Child {
    @ManyToOne
    private Parent parent; 

    private int pos;

    @ManyToOne
    @OrderedPeer(-1)
    private Child previous;

    @ManyToOne
    @OrderedPeer(1)
    private Child next;
}

I propose a new annotation @OrderedPeer that tells JPA that the annotated entity is a member of the same list of the current entity, and what relative offset it exists. There can also be an optional attribute that commands what to do when the index does not exist at access time; possible behavior includes return null or throw exception.






[JPA_SPEC-120] Clarify definition of basic type Created: 30/Oct/15  Updated: 30/Oct/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.2
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Harald Wellmann Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The term basic type is used throughout the specification, but it is not clearly defined.

Section 11.1.6 Basic Annotation reads

The Basic annotation
can be applied to a persistent property or instance variable of any of the following types: Java primitive
types, wrappers of the primitive types, java.lang.String, java.math.BigInteger,
java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date,
java.sql.Time, java.sql.Timestamp, byte[], Byte[], char[], Character[],
enums, and any other type that implements Serializable.

Is the intended meaning:

A basic type is any of the following types. [insert list].
The @Basic annotation can be applied to any basic type. The use of this annotation is optional.

A mapping exception shall be raised when the @Basic annotation is applied to any non-basic type.






[JPA_SPEC-119] Explore possibilities for using @Optional Created: 27/Oct/15  Updated: 27/Oct/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: Lukas Jungmann Assignee: Lukas Jungmann
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified





[JPA_SPEC-118] Allow simplified form for @NamedEntityGraph Created: 29/Sep/15  Updated: 19/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Lukas Jungmann Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Spin off from JPA_SPEC-98:

as of 2.1 definition of @NamedEntityGraph can be too verbose, see ie https://github.com/javaee-samples/javaee7-samples/blob/master/jpa/entitygraph/src/main/java/org/javaee7/jpa/entitygraph/Movie.java

It would be good to allow simplified form, ie:

@NamedEntityGraph(
    attributes = {"id", "name", "description", "subgraph.property", "anotherSubgraph.property"}
)


 Comments   
Comment by pbenedict [ 18/Nov/15 ]

I am not a fan of @NamedEntityGraph because attribute string names (1) aren't typically discoverable by IDEs for refactoring and (2) are too far removed from the actual fields themselves. What about allowing a second option – reversing the concept – so that attributes specify what graphs they belong to? I am sure there are use cases for both.

Example:

@Column
@NamedEntityGraphMember("movieWithActors")
private String name;
Comment by radcortez [ 19/Nov/15 ]

Seems a good idea, but it might harder to read which properties are loaded in each EntityGraph. I'm assuming, that a @NamedEntityGraphMember in a field property could have an array of graphs, so it would make it harder to read when you might have something like this:

@Column
@NamedEntityGraphMember({"graph1", "graph2", "graph3"})
private Long id;
@Column
@NamedEntityGraphMember({"graph2", "graph3"})
private String name;
@Column
@NamedEntityGraphMember({"graph2"})
private String anotherName;

You get the idea. It becomes more complex when you have an entity with more fields.





[JPA_SPEC-128] Support JOIN/ON for two root entities Created: 29/Mar/16  Updated: 02/Aug/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: virgo47 Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently JPA does not allow root entities after various JOIN clauses which means that especially outer joins cannot be specified and executed without association path. In some cases it may be beneficial when we can join even when the relation is not mapped, e.g. to avoid potentially EAGER One- or @ManyToOne relationship (LAZY is only hint, not guaranteed).

EclispeLink currently supports such joins and they add a lot of options how to solve some problems with a minimal JPQL change. "EclipseLink also supports usage of the ON clause between two root level objects." See: https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#ON

Please, consider root entites as candidates for joins.



 Comments   
Comment by neilstockton [ 29/Mar/16 ]

+1 for allowing JOIN to be to another "root" element. DataNucleus JPA also provides that IIRC.

But think this won't apply to "FETCH JOIN" which still needs to be along a relation, hence spec needs to distinguish the syntax difference between JOIN and FETCH JOIN.

Comment by c.beikov [ 02/Aug/16 ]

Hibernate also supports this kind of joins as of version 5.1: http://in.relation.to/2016/02/10/hibernate-orm-510-final-release/





[JPA_SPEC-111] Allow side-effect free check whether a named query is available Created: 21/May/15  Updated: 29/Nov/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently the only way to check whether a named query with a given name exists is calling EntityManager.createNamedQuery(…). Unfortunately the non-presence of a query is expressed by throwing an exception. That in turn causes a transaction currently in progress to be marked as to be rolled back:

Runtime exceptions thrown by the methods of the EntityManager interface other than the LockTimeoutException will cause the current transaction to be marked for rollback if the persistence context is joined to that transaction.

(from section 3.1.1. JPA 2.1 specification.

This means that even if the user code is able to mitigate this scenario, the currently running transaction will be broken. This has come up to be particularly problematic in the context of component systems that lazily instantiate application components (i.e. CDI) as this increases the probability of a business transaction already running when the EntityManager is created and used the first time.

Spring Data JPA currently tries to work around this by creating a dedicated EntityManager for the testing lookup. Also, in Spring environments application components are usually created eagerly so that it's less likely users run into these situations.

We introduced dedicated means to work around this in Spring Data but it seems to me that the fundamental issue – a plain lookup of something rolling back the transaction – is way too aggressive here.

If changing the behavior of EntityManager.createNamedQuery(…) is not an option, maybe providing a new method that allows to check for the presence of a named query could be an option to consider.



 Comments   
Comment by neilstockton [ 29/Nov/16 ]

NamedQueryDoesntExistException (extends RuntimeException) sounds like a simple solution for createNamedQuery. I don't see how backwards compatibility is affected with that, and then I can catch problems where I type a query name in wrong!





[JPA_SPEC-110] Lift requirement that MappedSuperclass, Entity and Embeddable classes must be top-level classes Created: 21/May/15  Updated: 21/May/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: flutter Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

all


Tags: embedded, entity, toplevel

 Description   

Currently, JPA Specification 2.1, section 2.1, paragraph 3, states:

> The entity class must be a top-level class

The section on @Embeddable classes, in turn, refers to that section.
It is my assumption that it would be quite safe also to allow static nested classes without posing too much problems to implementations.
So, I suggest to lift that requirement such that static nested classes are allowed as entities and/or embeddables.






[JPA_SPEC-97] Simplify referencing in JPA annotations Created: 16/Dec/14  Updated: 16/Dec/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: HajoLemcke Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Any



 Description   

The high fence to understand referencing in JPA and all the bugs in the implementing frameworks brought me to suggest a much easier approach:

Instead of all these @ManyToOne, @OneToMany, @OneToOne, @ManyToMany supported by additional (partially required) annotations like @JoinColumn and others I suggest just to map the database world into the Java world (which should be the goal of an OR-mapper anyway) by having only two annotations.

Referencing in the database world is achieved by one table having a column (or multiple) which references an entry in another (or even the same) table.

Why not just integrate this easy to understand subject into JPA?
Lets assume a database table named 'ParentTable' and a table named 'ChildTable' which has a column referencing 'ParentTable'.

The Java class named 'ParentClass' may have an object reference (or a collection) to 'ChildClass' which must be annotated with '@ReferencedBy( sourceEntity=ChildClass.class, sourceTable="ChildTable", sourceColumn="parentid" )'. If this is (currently) @OneToMany or @OneToOne is easily determined by the type of the property. If its a collection its @OneToMany.

The Java class named 'ChildClass' has the referencing column as a standard field like 'Long parentid = null;'. In addition it may have an object reference to its parent like 'ParentClass parent = null;' The new annotation here is '@References( targetEntity=ParentClass.class, targetTable="ParentTable", targetColumn="id" )'.

Additional parameters could be added to this two annotations like "nullable=", "onDelete=", "onUpdate=" ... which directly matches SQL.

Since there are two fields in 'ChildClass' (the column from the database table and the reference to the other class), setting them must follow some rules. But this is no more complicated than synchronizing a bidirectional relationship between two Java classes.

Example of setters in class 'ChildClass':
public void setParentid( Long parentid ) {
if ( parent != null && parent.getId() != parentid )

{ this.parent = null; }

this.parentid = parentid;
}

public void setParent( ParentClass parent ) {
this.parent = parent;
if ( parent != null ) {
this.parentid = parent.getId();
}}

This kind of setters could be ensured by bytecode manipulation, which is required in current framework implemantations anyway because the value of database column ChildTable.parentid must be stoerd somewhere.






[JPA_SPEC-96] Hint to prevent provider loading state beyond what graph specifies Created: 19/Nov/14  Updated: 19/Nov/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: arjan tijms Assignee: ldemichiel
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JPA 2.1 introduced the concept of fetch graphs and load graphs. In a fetch graph attributes that are specified are treated as EAGER.

Unfortunately, there is no strong facility to specify which data should definitely NOT be loaded. Often limiting what should be loaded is even more important than specifying what should be loaded.

The functioning of fetch graphs is specifically hampered by the very unfortunate appearance of section 3.7.4 in the JPA 2.1 spec:

The persistence provider is permitted to fetch additional entity state beyond that specified by a fetch graph or load graph. It is required, however, that the persistence provider fetch all state specified by the fetch or load graph.

I would like to propose adding either an additional hint, to be used together with the fetch and load graph hints, or two new hints in addition to the fetch and load graph hints, that forbid the provider to load any additional state beyond that what is specified.

The definition of these new hints could be something like:

The persistence provider is strongly forbidden to fetch any additional entity state beyond that specified by a fetch graph or load graph. It is required that the persistence provider fetch all state specified by the fetch or load graph.






[JPA_SPEC-102] Add datetime functions Created: 28/Feb/15  Updated: 28/Feb/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is currently no way to extract parts of a datetime attribute in a standardized way. Hibernate, EclipseLink and DataNucleus have support for that. I propose to add the functions:

  • YEAR
  • MONTH
  • DAY
  • HOUR
  • MINUTE
  • SECOND





[JPA_SPEC-99] Add ability to stream the result of a query execution Created: 21/Feb/15  Updated: 14/Sep/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: ldemichiel
Resolution: Unresolved Votes: 11
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to JPA_SPEC-89 Introduce scroll as alternative to ge... Open

 Description   

Reading large datasets using JPA is quite uncomfortable these days as all method signatures return {{List}}s, which causes the entire result set to be pulled into memory before it can be handed to clients. Currently users work around this by paging through the results which sort of works but is error prone regarding inserts and deletes that might touch the same set of data to be read causing inconsistencies while iterating.

It would be great if alternatives to access a Stream (on JDK 8) or an AutoCloseableIterable (on JDK 7) could be provided to lazily iterate over a result set, e.g. EntityManager.stream(…) analog to the find(…) methods as well as Query.getResultStream().

It might be worth thinking about being able to hand an eviction policy to those methods to define rules to evict managed types from the EntityManager as otherwise the persistence context will inevitably grow during the streaming operation.



 Comments   
Comment by yeroc [ 21/Feb/15 ]

Duplicate of JPA_SPEC-89?

Comment by Lukas Jungmann [ 14/Sep/15 ]

not sure if duplicate but at least related; considering for 2.2





[JPA_SPEC-107] Support subqueries in SELECT lists Created: 08/Apr/15  Updated: 08/Apr/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: dPiergies Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Whilst developing applications using JPA, we have repeatedly found ourselves in a situation where the restriction preventing subqueries from being used in SELECT lists poses a serious limitation, requiring us to work around the problem in one of several ways:

1. Rearrange the query to avoid using a subquery in the SELECT list. Not a problem, but not always possible (e.g. when a count of related entities is required).

2. Issue the subselect as separate queries. Not feasible in many situations as it requires an additional database query for every row returned by the original query. This can have a huge performance impact.

3. Denormalize our database schema so that the required data can be selected from a single table. This is acceptable in some circumstances, and indeed can boost performance for some operations, but in every instance we've come across the query containing the sub-select can be executed efficiently by the database, and it seems somewhat perverse to denormalize a database schema to work around limitations in the ORM API.

4. Resort to native queries. Not pretty. Breaks type safety and can easily lead to database portability issues. Makes problems such as limiting results for pagination and allowing variable sort orders far more complex to implement.

I really do hope that the next release of the JPA specification resolves this issue, as I believe that this restriction poses a serious limitation.






[JPA_SPEC-106] Clarify semantics of BindableType Created: 01/Apr/15  Updated: 01/Apr/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

BindableType has three values SINGULAR_ATTRIBUTE, PLURAL_ATTRIBUTE, ENTITY_TYPE.

For an entity like this:

class User {

  private User manager;
}

The lookup of the bindable type for the manager property returns ENTITY_TYPE on Hibernate and SINGULAR_ATTRIBUTE on EclipseLink. I'd argue the latter is wrong as the existence of ENTITY_TYPE indicates that it should be preferred over SINGULAR_ATTRIBUTE if the attribute indeed is a JPA entity. The spec however is completely silent on this and doesn't define any strict rules.






[JPA_SPEC-105] Allow AttributeConverter to be used for composite types by using @Embeddable Created: 26/Mar/15  Updated: 24/Oct/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Xavier Dury Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Right now, AttributeConverters can only be used for single-value types. They could be extended to use an @Embeddable type as a surrogate column type for composite types.

Imagine the immutable type Money(final BigDecimal amount, final Currency currency) and the following @Embeddable type:

@Embeddable
public class EmbeddableMoney {

	private BigDecimal amount;
	private Currency currency;

	// getters & setters
}

@Converter(autoApply = true)
public class MoneyConverter implements AttributeConverter<Money, EmbeddableMoney> {
	
	@Override
	public EmbeddableMoney convertToDatabaseColumn(Money attribute) {
		if (attribute == null) {
			return null;
		}
		EmbeddableMoney columns = new EmbeddableMoney();
		columns.setAmount(attribute.getAmount());
		columns.setCurrency(attribute.getCurrency());
		return columns;
	}

	@Override
	public Money convertToEntityAttribute(EmbeddableMoney dbData) {
		if (dbData == null) { // check if empty?
			return null;
		}
		return new Money(dbData.getAmount(), dbData.getCurrency());
	}
}

@Converter(autoApply = true)
public class CurrencyConverter implements AttributeConverter<Currency, String> {
	...
}

What do you think?



 Comments   
Comment by neilstockton [ 18/Apr/15 ]

Whilst this may cater for some types, it would do nothing for classes that the developer has no access to. If they wanted to map some type to 2 (or more) columns they couldn't.

What could be done is to take the existing AttributeConverter and use the second generic type (the column type) as Object[], so then the values of the column(s) can be obtained. An implementation would likely need to know the individual column types (since not obtainable from Object[]), hence add a new method

Class[] getDatabaseColumnTypes();

(or provide a new interface MultiColumnAttributeConverter (with this method above) that AttributeConverters implement should they want to persist to multiple columns).

Comment by Xavier Dury [ 20/Apr/15 ]

I don't understand how this could not be used for types the developer has no access to (as long as those types have a way to extract the necessary information to be persisted and there's a way to reconstruct objects based on that information, which btw is also needed when using Object[]).

In my example, EmbeddableMoney is used to (de)structure the Money type which is final and coming from an external library.

Another advantage of using an @Embeddable instead of Object[] is that you can annotate the properties with @Column and you can use those properties names in your query.

Comment by Xavier Dury [ 24/Oct/16 ]

Two more arguments to push this request:

1) No API change is needed, just a new interpretation of the second parameter of AttributeConverter<X, Y>
2) This is the way JAXB works too with its XmlAdapter

Example:

public class MoneyXmlAdapter extends XmlAdapter<MoneyXmlAdapter.Wrapper, Money> {
	
	public static class Wrapper {
		BigDecimal amount;
		Currency currency;
	}
	
	public Wrapper marshal(Money money) {
		if (money == null) {
			return null;
		}
		Wrapper wrapper = new Wrapper();
		wrapper.amount = money.getAmount();
		wrapper.currency = money.getCurrency();
		return wrapper;
	}
	
	public Money unmarshal(Wrapper wrapper) {
		if (wrapper == null || wrapper.amount == null || wrapper.currency == null) {
			return null;
		}
		return new Money(wrapper.amount, wrapper.currency);
	}
}




[JPA_SPEC-104] Enhance PersistenceUtil to allow initialization Created: 19/Mar/15  Updated: 19/Mar/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: paranoiabla Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello,

at the moment the javax.persistence.PersistenceUtil provides methods to determine the load state of an entity. It would be also nice if we had methods to initialize and unproxy if the entity is a proxy object. I know Hibernate already have this in the org.hibernate.Hibernate class. It would be nice to have a pure JPA solution.



 Comments   
Comment by neilstockton [ 19/Mar/15 ]

Not all JPA implementations have such a concept as a "proxied object", and the majority don't require you to initialise anything. I can't see how this should become standardised ... its based on Hibernate's implementation only AFAIK





[JPA_SPEC-103] Lift input parameter restrictions Created: 18/Mar/15  Updated: 18/Mar/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I just came across JPA spec 4.6.4 and I was shocked. Is there any reason to limit input parameters to WHERE and HAVING clauses?






[JPA_SPEC-94] javadoc compilation prints out warnings on JDK8 Created: 12/Oct/14  Updated: 12/Oct/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Lukas Jungmann Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Cloners
clones JPA_SPEC-91 javadoc compilation fails on JDK8 Resolved

 Description   

javadoc generation fails on JDK8 mainly due to improper escaping of html entities and incorrect usage of closing tags

Javadoc tool output
...
  [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/SqlResultSetMapping.java:36: error: bad use of '>'
  [javadoc]  *        "WHERE (order_quantity > 25) AND (order_item = i.id)",
  [javadoc]                                  ^
  [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/spi/PersistenceProvider.java:81: error: reference not found
  [javadoc]      * @throws PersistenceException if insufficient or inconsistent
  [javadoc]        ^
  [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/spi/PersistenceProvider.java:103: error: reference not found
  [javadoc]      * @throws PersistenceException if insufficient or inconsistent
  [javadoc]        ^
  [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/spi/PersistenceProviderResolverHolder.java:41: error: unexpected end tag: </code>
  [javadoc]  * environment, the default </code>PersistenceProviderResolver is used.
  [javadoc]                             ^
  [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/spi/PersistenceUnitInfo.java:35: error: element not closed: code
  [javadoc]      * <code>name</code> attribute in the <code>persistence.xml<code> file.
  [javadoc]                                                                ^
  [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/spi/PersistenceUnitInfo.java:35: error: element not closed: code
  [javadoc]      * <code>name</code> attribute in the <code>persistence.xml<code> file.
  [javadoc]                                           ^
  [javadoc] 19 errors
  [javadoc] 100 warnings


 Comments   
Comment by Lukas Jungmann [ 12/Oct/14 ]

this is invalid, correct issue is JPA_SPEC-95





[JPA_SPEC-83] Require lazy registration of entity listeners after createContainerEntityManagerFactory() call Created: 10/Jul/14  Updated: 21/Nov/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: Improvement Priority: Major
Reporter: smarlow Assignee: ldemichiel
Resolution: Unresolved Votes: 7
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2014-01/message/3 didn't get much feedback but https://issues.jboss.org/browse/WFLY-2387 has gotten interest. The issue is that CDI injection allows you to inject the persistence context, and listeners support CDI injection, which may need the same persistence unit (causing a cycle). One way to resolve the cycle, is to ensure that persistence units always are available before the entity listeners are registered.

Add a requirement that entity listeners are registered after the EntityManagerFactory is created (after createContainerEntityManagerFactory(PersistenceUnitInfo, Map) returns) and before it is needed by the application.



 Comments   
Comment by smarlow [ 18/Jul/16 ]

Revised suggested requirement change, to allow entity listener to be registered any time after EntityManagerFactory is available, as long as the entity listener is registered before it is needed. This allows the entity listener to be registered on first use or any time after the createContainerEntityManagerFactory() call returns.

Comment by smarlow [ 22/Jul/16 ]

I think that we need to clarify how soon the entity listener can be registered. Just after the createContainerEntityManagerFactory() might be too soon. It might need to be after the javax.enterprise.inject.spi.AfterDeploymentValidation has triggered.





[JPA_SPEC-90] Introduce row value constructor syntax Created: 13/Aug/14  Updated: 13/Aug/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

SQL-92 introduced the row value constructor and JPA should support it. Even though some databases do not support the syntax of SQL-92, it can be emulated as has been shown by JOOQ:

Hibernate even supports that syntax already as document here: https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html_single/#queryhql-tuple

The changes in the JPQL BNF would require to copy the following rules and giving the copies a suffix like '_1'.

  • arithmetic_primary
  • string_expression
  • boolean_expression
  • enum_expression
  • datetime_expression
  • entity_expression
  • entity_type_expression

Then transform the original rules like the following where R is the respecitve rule name

R ::= R_1 | { (R_1 {, R_1}*) }

Of course the naming is stupid but it allows this generic transformation description.

Null comparison and IN expressions follow the same scheme

null_comparison_expression ::=
	{null_comparison_expression_simple | {( null_comparison_expression_simple {, null_comparison_expression_simple}* )} } IS [NOT] NULL
null_comparison_expression_simple ::=
	{single_valued_path_expression | input_parameter}

in_expression ::=
	in_expression_lhs [NOT] IN
		{ ( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter }

in_expression_lhs ::=
	in_expression_lhs_simple | {( in_expression_lhs_simple {, in_expression_lhs_simple}* )} )
in_expression_lhs_simple ::=
	{state_valued_path_expression | type_discriminator}

in_item ::=
	in_item_simple | {( in_item_simple {, in_item_simple}* )} )
in_item_simple ::= literal | single_valued_input_parameter

And finally the subquery should also be able to have more than one select item.

simple_select_clause ::= SELECT [DISTINCT] simple_select_expression {, simple_select_expression}*





[JPA_SPEC-89] Introduce scroll as alternative to getResultList Created: 13/Aug/14  Updated: 14/Sep/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 6
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to JPA_SPEC-99 Add ability to stream the result of a... Open

 Description   

Since Java 8 was much about streams, parallelism and so on, I guess it only makes sense to extends javax.persistence.Query to also offer a method, that returns something like hibernates org.hibernate.ScrollableResults.
Since Java 8 introduced Stream JPA could introduce something like a ResultStream that additionally supports scrolling.
This would make it possible to use JPA for big amounts of data



 Comments   
Comment by Lukas Jungmann [ 14/Sep/15 ]

considering for 2.2





[JPA_SPEC-88] Pagination in JPQL and Criteria API Created: 13/Aug/14  Updated: 13/Aug/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JPA supports pagination but only on the outermost query. As described in the following article from JOOQ developers, it is possible to generate proper SQL for paginated subqueries.

http://blog.jooq.org/2014/06/09/stop-trying-to-emulate-sql-offset-pagination-with-your-in-house-db-framework/

I propose to add a pagination clause to JPQL and some methods to the Criteria API.

JPQL:

limit_clause ::= [LIMIT arithmetic_expression] [OFFSET arithmetic_expression]

Replace current statements with the following. Note that subquery now also needs to support orderby_clause and that limit_clause can only be used in conjunction with orderby_clause

select_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [(orderby_clause) | (orderby_clause limit_clause)]
subquery ::= simple_select_clause subquery_from_clause [where_clause] [groupby_clause] [having_clause] [(orderby_clause) | (orderby_clause limit_clause)]

Criteria API

javax/persistence/criteria/AbstractQuery.java
AbstractQuery<T> orderBy(java.util.List<Order> o) 
AbstractQuery<T> orderBy(Order... o) ;
AbstractQuery<T> limit(Expression<? extends Number> limit);
AbstractQuery<T> offset(Expression<? extends Number> offset);

and some covariant overrides for the subquery

javax/persistence/criteria/Subquery.java
Subquery<T> orderBy(java.util.List<Order> o) 
Subquery<T> orderBy(Order... o) ;


 Comments   
Comment by c.beikov [ 13/Aug/14 ]

Here a little example. If I want to paginate a query like the following

SELECT
    u
FROM
    User u
LEFT JOIN FETCH
    u.loginLogs
ORDER BY
    u.name

I can't use setFirstResult/setMaxResults on the query. So I have to use the following workaround

1. Fetch ids

SELECT
    u.id
FROM
    User u
ORDER BY
    u.name

2. Fetch entities

SELECT
    u
FROM
    User u
LEFT JOIN FETCH
    u.loginLogs
ORDER BY
    u.name
WHERE
    u.id IN :ids

Where the parameter ids will be set with the result of the first query.
Now if subqueries would allow some kind of LIMIT clause, I could turn that into a single query.

SELECT
    u
FROM
    User u
LEFT JOIN FETCH
    u.loginLogs
ORDER BY
    u.name
WHERE
    u.id IN (
	SELECT
		u.id
	FROM
		User u
	ORDER BY
		u.name
	LIMIT
		:maxResults
	OFFSET
		:firstResult
    )




[JPA_SPEC-87] Provide JPA equivalent to Hibernate Filters Created: 28/Jul/14  Updated: 13/Aug/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: paranoiabla Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello guys,

following this question:

http://stackoverflow.com/questions/19361166/jpa-equivalent-for-hibernate-filters

I would like to suggest that you include JPA equivalent to Hibernate's Filter. I'm using the filters of hibernate quite a lot and I think they are very helpful, so now i'm bound to use hibernate and I can't switch my JPA implementation.



 Comments   
Comment by c.beikov [ 13/Aug/14 ]

If Filters were added, it would be useful for libraries if we could add them before the EntityManagerFactory is constructed.
Also see JPA_SPEC-12





[JPA_SPEC-86] Allow multiple level @InheritanceType Created: 28/Jul/14  Updated: 28/Jul/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: paranoiabla Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello,

at the moment the spec says the annotation InheritanceType can be used only once - any subsequent uses are just ignored. My suggestion is to allow for multiple uses of this annotation.
For example let's say I have the following hierarchy:

AbstractEntity (with InheritanceType=TABLE_PER_CLASS)
 \--Product
 \--Widget (with InheritanceType=SINGLE_TABLE)
     \--Map
     \--Carousel
     \--Banner

I would expect Product and Widget to be in their own tables, but Map, Carousel and Banner to be all in the Widget table. However, currently this is not supported.






[JPA_SPEC-85] Add methods in Metamodel interface to get entity by jpa name Created: 28/Jul/14  Updated: 28/Oct/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: paranoiabla Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello guys,

following this one:

https://www.java.net/forum/topic/glassfish/glassfish/how-obtain-class-j
pa-entity-name

and this one:

https://hibernate.atlassian.net/browse/HHH-9217

let's say I define an entity like this:

@Entity(name = "car")
public class Car {
}

now I want to get the EntityType by the name value (by "car").
Unfortunately this seems to be impossible I can get hold of the
EntityManager and from there I can get the Metamodel interface, but in
there I can see only one method which accept a class object:

<X> EntityType<X> entity(Class<X> cls);

I would like to propose several new methods to be included:

<X> EntityType<X> entity(String jpaEntityName);

<X> ManagedType<X> managedType(String jpaEntityName);

<X> EmbeddableType<X> embeddable(String jpaEntityName);

It seems quite logical to get the entity by the name it was given
(otherwise what' really the purpose of this name). And, yes, I know
about the solution where you get all the entities and iterate in a loop
and compare their names with the one you have, but I guess you would
agree this is a really poor performancewise. Another plus to this is
that the underlying implementation would be super-easy: just keep the
jpaEntityNames in a map (even for hibernate I have provided a 1-line
patch).

Please let me know what you think.

Thanks, and keep up the good work.



 Comments   
Comment by neilstockton [ 28/Oct/16 ]

The clear problem with those methods (not arguing against the usefulness) is that your generic "X" is undefined. The existing methods with a class define the X, yet when you have no class and instead a String then the user would have to spend their time casting





[JPA_SPEC-80] A standard way to obtain custom SQLSTATE issued by batches, triggers and stored procedures Created: 21/May/14  Updated: 21/May/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Rather any RDBMS is able to define custom SQLSTATEs. This becomes useful when writing batches, triggers and stored procedures, as the business logic inside that SQL programs has the ability to stop processing and inform the caller on business level exceptions (like "Account limit exceeded." encoded as SQLSTATE 'ATM13' when a user invokes "CALL ATM_withdraw(5000.00)" in a banking application). Sophisticated front ends (hence, calling applications) might want to differentiate between several custom SQLSTATEs (e. g. SQLSTATE 'ATM13' compared to 'ATM27' which might be a completely different business level reason to stop processing of the SQL program).

JDBC defines an unambiguous way to obtain these custom SQLSTATEs by SQLException.getSQLState(). Unfortunately, JPA does not but enforces product-specific workarounds. While some standard outcomes are provided as specialized PersistenceExceptions (e. g. EntityExistsException, EntityNotFoundException, etc.) there is no special exception for "custom causes". Also, it is not clearly said that EACH compliant entity manager MUST provide an SQLException containing the root cause to the PersistenceExceptions. While EclipseLink does provide this SQLException, it does not as a direct cause of PersistenceException. It seems to be even valid that compliant entity managers do not provide the causing SQLException at all.

As a solution I could imagine two alternatives:

(A) Define in the JPA spec that in case an entity manager is using JDBC to execute SQL statements, any thrown SQLExceptions MUST be returned DIRECTLY by PersistenceException.getCause().

(B) Define in the JPA spec that in case a database backend operation results in an unknown SQLSTATE, the returned PersistenceException MUST be an instance of the new class UnknownSQLState, and can be obtained by invoking UnknownSQLState.getSQLState().

While (A) is expected to be rather simple to implement by ORM vendors, in fact it is (B) which would provide the most unambiguous and simple solution to the application programmer.






[JPA_SPEC-79] EntityManager.createStoredFunctionQuery -- Using return values instead of result sets Created: 19/May/14  Updated: 19/May/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JPA 2.1 provides a facility to call stored procedures, which greatly improves performance in many situations.

Unfortunately, it does not yet provide the same feature richess of JDBC. One partocular missing feature is the ability to read the result of a stored FUNCTION: The technical way to read those is defined by JDBC API, but not by JPA!

In JDBC, a return value can be simply queried by reading the OUT parameter at index 0, which is valid for all escaped functions when using the syntax {?=call myfunc(...)}. In JPA, providing a leading question mark leads to syntax errors. While using a native query using "SELECT myfunc(...)" certainly does work, it leads to unwanted performance overhead and code clutter, as it creates a CURSOR and wraps it using a JDBC ResultSet, possibly inducing additional network roundtrips to get that CURSOR's description and first row. JDBC prevents this by simply requesting the sole function result value as a side effect of the call, which is certainly available in the same roundtrip.

Hence, to spare overhead, improve performance and reduce application code size, it would be really great if JPA learns to deal with stored FUNCTION result values, just as JDBC can do it since many years.

A proposed syntax would be:

StoredFunctionQuery q = em.createStoredFunctionQuery("MyFunc(...)");
q.registerOutputParameter(0, Integer.class, OUT);
q.execute();
int = g.getParameter(0); <-- Returns value of '?=' in JDBC






[JPA_SPEC-74] Obtaining @Version value Created: 17/Feb/14  Updated: 08/Dec/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I want to suggest that a future release of the JPA API provides a means to get the value of an entities version attribute.

Example: em.getVersion(myEntity);
he
Justification: Generic frameworks like JAX-RS or Servlets might have an interest in getting the value of the version attribute without "knowing" which is "the version attribute" for any particular entity. For example, JAX-RS or Servlets want to send a ETag header to a client for any entity, but the Servlet does not "know" the class of that entity. Like when class name and primary key value are provided by a HTTP request. In that case, a solution would be em.getVersion(myEntity) which just should return the value of the version.



 Comments   
Comment by mkarg [ 17/Feb/14 ]

An improvement ontop would be em.isCached(Class<?>, id, version) which returns true or false, depending on the fact whether the EM has an entity with that primary key and version in cache.

Justification: To answer conditional HTTP requests it would be great to query the cache for a particular version. If the cache does not contain that version, EM shall NOT load from disk, but answer to JAX-RS or Servlet that this entity is not there.

Comment by pbenedict [ 23/Nov/15 ]

I think this is more of a design issue than a needed JPA enhancement. If you want to generate ETag values off any entity, for example, you should create integration logic that knows how to do the transformation. I don't understand why you want to avoid having to know the version attribute; it's not poor design to expose it. Just go ahead and create a universal interface that all your versioned entities can implement:

public interface Versioned {
    int getVersion();
}

PS: Caching is supported now by JPA 2.0 @Cacheable; this should alleviate your concern about always materializing an entity.

Comment by mkarg [ 24/Nov/15 ]

By design, I do not want to add a superfluous interface: JPA already knows the attribute, so it makes no sense to add another interface, as your compiler cannot guarantee that it accesses the same attribute as the annotation uses – risk of hard to track bugs! ALso, the attribute might be invisible to the accessing package on design purpose and adding an interface enforces "public" visibility. You simple will copy existing technology for the sake of not adding a needed JPA feature.

Also my proposal will work with ANY entity – even entities that the caller has no source code of, hence, cannot add the proposed interface!

@Cacheable actually does not solve the described use case. I do want to load from disk exactly in case the ETag is not matching. @Cacheable(false) prevents this.

Comment by pbenedict [ 24/Nov/15 ]

That is an interesting requirement. I've always been in control of my entities so I haven't encountered your dilemma. If the version isn't being exposed to you in a third-party entity, there may be a good design reason for that (or not). Someone from the EG should opine. I think the question boils down to this: For any given entity, is the value contained in a @Version attributed considered to be intrinsically public? If so, then expose it through the EM.

Comment by mkarg [ 24/Nov/15 ]

Yes, in fact our application provides services upon any "unknown" set of entities provided by third parties: We accept JPA QL and we return entities – without care of the entity classes, its interface, or its source. Hence we need to be able to handle their version without deeper knowledge, but solely must go through an JPA API.

BTW, we do not see that the @Version member implicitly has to be public, as we do not want to access the member. We only want to either ask the EM to expose the version value, or even better, simply ask whether a known version still is current or not.

Comment by neilstockton [ 08/Dec/15 ]

This requirement seems reasonable to me, and is already available in the JDO API. In JDO you can also have a surrogate version (i.e no field in the class, but the version managed by the persistence solution). That would also be a useful requirement for JPA (FWIW)





[JPA_SPEC-73] Parameterized AttributeConverter and/or AttributeConverter metadata access Created: 07/Feb/14  Updated: 23/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: frenchc Assignee: Unassigned
Resolution: Unresolved Votes: 9
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It would be good if we were able to parameterize AttributeConverter instances and/or have access to property metadata within an AttributeConverter. This way we are able to reuse AttributeConverter code instead of building similar ones or even supply further required context information. An example:

Quite often we have to deal with ancient DB schemas, and just recently we started to migrate a large Cobol application to Java. We are unable to change the content of the database, and because of Cobol with have to support fixed width string columns containing left padded data. A 5 digit fixed width column will represent 1 as '00001' and 100 as '00100'. Nothing we can change here. Unless I am mistaken I have to create a dedicated converter for every required fixed length ending up with an LeadingZeroTwoDigitAttributeConverter, LeadingZeroFiveDigitAttributeConverter and so on.

Right now it seems the JPA spec does not define wether there is one converter instance per persistent property or just a global one (which would be OK by current spec requirements). I would propose that parameterized converter instances are bound to property fields in order to support parameter evaluation during JPA provider startup.

I believe we need access to both basic attribute information and optionally supplied converter attributes. The following example would assume access to the leading pad char, the length attribute and wether the attribute is nullable or not. (in my current project I have to store an empty string for null values in the database).

@Convert(converter = LeadingDigitAttributeConverter.class, metaData="padChar=0" )
@Column(name = "ACOLUM", length=5, nullable = false)

If you believe there is no need to support something like that: Unfortunately we are in the middle of migrating quite a few very very old applications to Java, and we can't change that stuff. And there is more to come.



 Comments   
Comment by c.beikov [ 15/Apr/14 ]

I agree that metadata is needed but I guess it would be easier to just let the converter instance know about the metamodel Attribute instance or something simialar.
You can define your own annotations that can be used for configuration purposes of the converter. Through the metamodel you can get your hands on those values.
I propose that you can either inject that instance or with java 8 default methods around, introduce a new default method "void init(javax.persistence.metamodel.Attribute)" in the AttributeConverter.

Comment by frenchc [ 15/Apr/14 ]

Sounds good to me.

Comment by tomdcc [ 30/May/14 ]

We have need of this as well - we'd like to convert enum attributes to specific string representations in the database, and with the current spec we have to create a converter per enum, rather than e.g. having the enum classes implement an interface to make the required string available and use a single converter.

Hibernate has parameters that you can pass to their converter types which is a workaround for this, but we're not using Hibernate for this project and in any case it's pretty ugly to have to do that for every column.

Making the metamodel attribute available to the converter would be perfect, as it could then grab the attribute type. The nice thing about that approach, too, is that if someone wants to pass extra info in to the converter that isn't available in the normal JPA model, they can create a custom annotation and the converter can call attribute.getJavaMember() and look for annotations, and the info is right with all the other metadata for the attribute.

Comment by isk0001y [ 23/Dec/14 ]

Such a parameterized AttributeConverter may also be of help when one is creating converter for hundreds of enums.
In our project we have approx. 260 enums, which implement a simple interface.

I can use the AttributeConverter to persist any enum implementing that interface, by just calling "getFoo()"; assuming getFoo() will return a basic type like string, the direction to the database is problem-free.
However, since I cannot parameterize the Converter, and I have no access to the Property-Type in the entity the converter is about to be applied, I cannot reversely find out the Enum-Class whose foo i had persisted.
This end me in creating over 260 Converters alongside 260 enums.

Both eclipselink and hibernate provide have solutions for this. Eclipselink allows me to use their "Converter" infrastructure to create Converters with a special "initialize" method that allows me to access the entity property being converted. Hibernate allows me to create "UserDefinedTypes" like "UserType", where the @Type annotation takes an array of @Parameters to configure the converter. Both techniques result in me creating only ONE converter, but any entity class is then dependent on the concrete JPA provider through imports. This cannot be what you guys want

If I already must stick to one JPA provider, then I completely can skip using jpa at all, and stay incompatible.

Comment by uk.wildcat [ 28/Aug/15 ]

For the slow, can someone provide an example of the workaround that c.beikov is outlining here

You can define your own annotations that can be used for configuration purposes of the converter. Through the metamodel you can get your hands on those values.

Comment by c.beikov [ 28/Aug/15 ]

You just define your own annotation type like

public @interface MyAnnotation {
String padChar();
}

and use it on your field or getter

@MyAnnotation(padChar = "0")
@Convert(converter = LeadingDigitAttributeConverter.class)
private String myField;

then when you have access to the javax.persistence.metamodel.Attribute you can get access to the member and via reflection access the MyAnnotation instance.

Comment by pbenedict [ 23/Nov/15 ]

I think this is easily possible with some design enhancement. Food for thought:

1) Once converters are injectable (JPA_SPEC-109), that means they will have a controllable lifecycle. Converters that are parameterized obviously cannot be singletons because they require customization per instance.

2) Enhance @Converter to allow an array of parameterized key/value pairs. The key represents a setter method on the converter instance.

// setPadChar must exist on LeadingDigitAttributeConverter
@Convert(converter = LeadingDigitAttributeConverter.class, parameters=@ConverterParameter(name="padChar", value="0"))
private String myField;

3) By new rule of the spec, any converter that has "parameters" are non-singletons.





[JPA_SPEC-72] Allow @PersistenceContext to be used on parameters ot enable constructor injection of EntityManagers Created: 07/Feb/14  Updated: 25/Mar/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently it's not possible to inject EntityManagers into constructors as @PersistenceContext is defined to not be allowed on parameters. it would be cool to enable this as users could then design application components using constructor injection only.



 Comments   
Comment by arjan tijms [ 25/Mar/14 ]

Wouldn't this automatically be possible when those contexts can be injected with @Inject?





[JPA_SPEC-71] Add subquery(EntityType) to javax.persistence.criteria.CriteriaQuery Created: 27/Jan/14  Updated: 27/Jan/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: koehn Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: entitytype, subquery

 Description   

If using dynamic entities not defined by classes (as is the case when using EntityMode.MAP), there's no way to create a subquery. This is because javax.persistence.criteria.CriteriaQuery.subquery() takes an entity Class as an argument, and unlike javax.persistence.criteria.CriteriaQuery.from() there's no overloaded method to subquery by EntityType. This severely limits what can be done using entities mapped with EntityType for which there is no Java class.






[JPA_SPEC-76] Allow specification for null handling in order-by expressions (JPQL and Criteria API) Created: 17/Mar/14  Updated: 13/Aug/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Oliver Gierke Assignee: Unassigned
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

§4.9 of the specification explictly states:

SQL rules for the ordering of null values apply: that is, all null values must appear before all non-null values in the ordering or all null values must appear after all non-null values in the ordering, but it is not specified which.

However, pretty much all of the important JPA providers support a nulls first/nulls last clause. So while it is already possible to define the strategy, it would be cool if one could reliably use it on top of JPA.



 Comments   
Comment by c.beikov [ 13/Aug/14 ]

Also not that this is important for database exchangeability. If I didn't specify nulls first or nulls last every query that uses the order by is non-portable between databases since databases have different defaults.





[JPA_SPEC-75] @Index.columnList should be an array Created: 11/Mar/14  Updated: 11/Mar/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: roxton Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In the JPA 2.1 specification, @Index has a String columnList property, and the specification presents this as a comma-delimited list. I propose that the specification be modified to make this property of type String[], both as a less surprising syntax and as an easier leap from Hibernate syntax.






[JPA_SPEC-78] TupleTransformer Created: 15/Apr/14  Updated: 13/Aug/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The constructor syntax in JPQL is limited by the fact, that the class must be visible to the classloader of the persistence provider. Also one might want to apply a custom transformation strategy based on metadata that does not use constructors but factories, builders or setters. To overcome these limitations I propose the addition of a TupleTransformer interface which can be implemented by a user to provide custom strategies.

TupleTransformer.java
public interface TupleTransformer<X> {
  List<X> transform(List<Tuple> tuples);
  X transform(Tuple tuple);
}

and an addition to Query and TypedQuery:

Query.java
public interface Query {
  // other methods
  Query setTupleTransformer(TupleTransformer<?> tupleTransformer);
}
TypedQuery.java
public interface TypedQuery<X> extends Query {
  // other methods
  <Y> TypedQuery<Y> setTupleTransformer(TupleTransformer<Y> tupleTransformer);
}

For reference see the ResultTransformer of Hibernate: http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/transform/ResultTransformer.html



 Comments   
Comment by c.beikov [ 13/Aug/14 ]

EclipseLink provides something similar(org.eclipse.persistence.queries.QueryRedirector) which can be used to do the same as with hibernate ResultTransformer.
If I understood it right, OpenJPA supports that with org.apache.openjpa.kernel.exps.AggregateListener, so every major JPA provider kind of already has that feature. Time to standardize





[JPA_SPEC-70] Allow two phase bootstrap approach to creating the EntityManagerFactory Created: 09/Jan/14  Updated: 09/Jan/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: smarlow Assignee: Unassigned
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Introduce a standard two phase persistence unit bootstrap and require that certain services are not accessed until the second phase. This will improve how JPA/CDI + JPA/@DataSourceDefinition work together.

In a perfect world, the first persistence unit bootstrap phase should not use the datasource or the CDI bean manager (instead wait for the second phase). Class enhancing/rewriting should also occur in the first phase (before application classes have been read).

This will help avoid use of the CDI bean manager too early (which otherwise can cause application entity classes to be loaded before they are enhanced/rewritten).

This will help avoid use of a datasource that is being deployed with the application (@DataSourceDefinition) but may not be available for use yet.

Also see discussion at https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2013-06/message/0.



 Comments   
Comment by arjan tijms [ 09/Jan/14 ]

+1!

This will also help or even be the solution for JAVAEE_SPEC-30

One question though; the two phases are thus needed for @DataSourceDefinition, but what about data sources that are defined in web.xml, ejb-jar.xml or application.xml.

Can't they be scanned and processed first without requiring the two phases?

Comment by smarlow [ 09/Jan/14 ]

One question though; the two phases are thus needed for @DataSourceDefinition, but what about data sources that are defined in web.xml, ejb-jar.xml or application.xml.

Data sources that are defined in web.xml, ebj-jar.xml or application.xml should also benefit by the change to bootstrap the persistence unit via two phases.

Can't they be scanned and processed first without requiring the two phases?

It will vary between application server implementations, when the data sources are available. On application servers that can start the data source earlier, supporting the two-phase pu bootstrap will also improve CDI injection in entity listeners (creating the bean manager will not prevent entity class enhancement).





[JPA_SPEC-69] Lift restriction limiting select clause to single-valued expression Created: 07/Jan/14  Updated: 01/Dec/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: arjan tijms Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Section 4.8 of the JPA spec defines that a select expression is limited to a single-valued path expression.

Since there doesn't seem to be a clear reason for this restriction I would like to request to remove it. This will make it easier to e.g. construct a DTO from an entity where a collection attribute needs to be included.

See also: https://java.net/projects/jpa-spec/lists/users/archive/2014-01/message/0



 Comments   
Comment by c.beikov [ 13/Aug/14 ]

This is fixed in JPA 2.1 isn't it?

Comment by kithouna [ 01/Dec/14 ]

This is fixed in JPA 2.1 isn't it?

No, not fixed. Still open!





[JPA_SPEC-57] Support schema drop on restart Created: 11/May/13  Updated: 11/May/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: reza_rahman Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

javax.persistence.schema-generation.database.action=drop-and-create only drops the schema on undeploy/deploy. For rapid/agile/iterative development via IDEs, very frequently developers start and stop the app/server without necessarily triggering a deploy/undeploy cycle hence not performing a drop. In these scenarios, developers would want a schema drop to happen on app/server stop and start. Hibernate for example, supports this feature.

Such a feature could be supported via an additional property like javax.persistence.schema-generation.database.drop-on-restart=true, that is defaulted to false.



 Comments   
Comment by reza_rahman [ 11/May/13 ]

Do let me know if anything needs to be explained further - I am happy to help.

Please note that these are purely my personal views and certainly not of Oracle's as a company.

Comment by Mitesh Meswani [ 11/May/13 ]

javax.persistence.schema-generation.database.action=drop-and-create only drops the schema on deploy.

There might be scenarios where we might want to clean up database on undeploy. It would be nice to have an option where EMF.close() triggers a drop





[JPA_SPEC-56] @Convert annotation's converter property should be Class<? extends AttributeConverter>, not Class (unsafe) Created: 04/May/13  Updated: 10/Dec/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Nick Williams Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: 1 hour
Time Spent: Not Specified
Original Estimate: 1 hour


 Description   

Currently, the converter property for the @Convert annotation is declared as follows:

Class converter() default void.class;

However, along with just generally being unsafe ("safe" use would be Class<?>), this does not properly restrict the set of classes that can be specified. My understanding is that this MUST be a class that implements javax.persistence.AttributeConverter. Therefore, the converter property should be specified like so:

Class<? extends AttributeConverter> converter() default void.class;

With this change, the developer will know at compile time if he has specified an incorrect class. Without this change, the developer will not know until he gets a runtime error, which is seriously less desirable.



 Comments   
Comment by neilstockton [ 17/May/15 ]

You can't do that.

Class<? extends AttributeConverter> converter() default void.class;
would not compile. "void.class" is not castable to the generic form (but is to the non-generic form, hence probably why they did it).

Comment by Xavier Dury [ 10/Dec/15 ]

Well, you can always do something like this:

public @interface Convert {

  interface NoConversionAttributeConverter extends AttributeConverter<Object, Object> {}

  Class<? extends AttributeConverter<?, ?>>converter() default NoConversionAttributeConverter.class;
  ...
}




[JPA_SPEC-62] Standard name and value for "read-only" query hint Created: 22/Jun/13  Updated: 11/Dec/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Relational databases typically benefit from the knowledge, whether a transation will potentially modify and information (so locks are needed), or only read-only queries are executed (so no locks are needed). For similar reason, EclipseLink (and hopefully other JPA implementations, too) know query hints for "ready-only".

Unfortunately when using such vendor-specific hints, this will induce the problem that a portable application must know all these hints for all JPA implementations (or there will be no Performance gain for the unknown ones). This is not smart from the view of an ISV.

Hence I want to propose that the next maintenance release of the JPA specification defines a unique name and value to enable the read-only query mode independently of the actual JPA implementation.

Proposal: A compliant implementation which has a read-only query mode MUST enable this read-only query mode when the "javax.persistence.readonly" with a value of "true" is provided.



 Comments   
Comment by mkarg [ 09/Dec/15 ]

I would really appreciate it if someone of the JPA spec team could at least comment on this more than two years old proposal.

Comment by Lukas Jungmann [ 11/Dec/15 ]

this make sense to me. Should check if there are other useful/commonly used hints to be defined by the spec.

Comment by pbenedict [ 11/Dec/15 ]

For clarity's sake, EclipseLink's "read-only" hint regards how it manages the first-level cache during a query; it's not about a making the transaction read-only.

Comment by mkarg [ 11/Dec/15 ]

A general "read-only" JPA property should simply allow the application programmer to tell JPA that the result of the query will never get updated by the current transaction. Whetever conclusions a JPA implementation draws from this is completely up to the particular JPA implementation. If EclipseLink simply uses this internally for its own cache purposes, this is a valid use. Other implementations might additionally or instead use this flag to send a "FOR READ ONLY" hint to the JDBC driver so the database can relax locking, etc.





[JPA_SPEC-61] Retrieving primary key of lazy relationship Created: 18/Jun/13  Updated: 15/Apr/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JPA 2.0



 Description   

My server passes entities to clients as XML representations, simply by marshalling it using JAXB. This works well but there is one case where it fails: LAZY relationships. As I just want to include a URL for each reference (so clients can decide on their own whether to load this in turn), I need access to the primary key. But, as it is a LAZY reference, the attribute itself is NULL, and if I use the getter(), then the complete entity is instantiated – which I do not need and do not want. So it would be really great, if there would be solution, which makes JAXB and JPA work more closely. Like an API to get the primary keys of LAZY relationships, or even better, an automatic integration.



 Comments   
Comment by mkeith [ 18/Jun/13 ]

Markus,

With JPA 2.1 you could create an entity fetch graph for the related object and only load the PK. You would effectively have an unloaded object (except that it would have the PK) with its remaining state set to lazily load. There are some differences between this and having the whole object be lazily loaded since if the object ends up getting triggered then, depending upon the implementation, each of the attributes may end up getting loaded separately, but it could be configured to be fairly close I think. Of course, this would be a bit of a pain if you needed to do this for every lazy loaded attribute, but the advantage would be that it would also work pretty well for collection-oriented relationships.

-Mike

Comment by mkarg [ 19/Jun/13 ]

Unfortunately didn't find a tutorial on this on the web.

Currently I am doing this...

Foo f = em.find(Foo.class, myFooPK);
jaxbMarshaller.marshal(f);

...to get the root. Can you provide an example how to use that "fetch graph" thing to get the PKs of f's LAZY relations?

Thanks!
-Markus

Comment by mkeith [ 19/Jun/13 ]

From your first comment it sounded like you already had something (e.g. an XMLAdapter or some such thing?) on the relationship attribute to control marshalling a URL instead of the target Bar related object. Assuming that is the case (you need to stop the JAXB marshaller from continuing to traverse the Bar object) then you just need to access the PK of the Bar, right? If this is your usecase then you could do the following:

Define a named entity graph for Bar:
@Entity
public class Bar {
@Id long id;
public int getId()

{ return id; }


...
}

@XmlRootElement
@Entity
public class Foo

{ ... @XmlJavaTypeAdapter(MyBarToUrlAdapter.class) @OneToOne Bar bar; ... }

and then to read the Foo instance, you would do:

Map<String,Object> props = new HashMap<String,Object>();
props.put("javax.persistence.fetchgraph", em.createEntityGraph(Bar.class));
Foo f = em.find(Foo.class, myFooPK, props);
...

From within your adapter, or whatever you use to convert a Bar to a URL, you could get the id of the bar by calling getId() and the rest of the object will likely not be loaded (likely, because lazy does not imply not loaded). If this doesn't describe your problem then we can take this discussion offline.

Comment by arjan tijms [ 22/Jun/13 ]

It would be great if there was a way to just grab the PK of any entity, regardless of how it was loaded.

After all, we know the PK must be there as JPA uses it to lazy load the associated entity. It's just that the default mapping that we normally do with JPA doesn't give us access to this PK.

Maybe PersistenceUnitUtil would be an ideal place to put a utility method that can do this. It already contains functionality that's in the same category.

E.g.

Given

@Entity
public class Foo {

    @Id
    Long id;

    @OneToOne(fetch = LAZY)
    Bar bar;

    // + getters/setters
}

@Entity
public class Bar {

    @Id
    Long id;

    // + getters/setters
}

We could then grab the PK of Bar given an instance of Foo and an EntityManager em, as follows:

PersistenceUnitUtil persistenceUnitUtil = em.getEntityManagerFactory().getPersistenceUnitUtil();

Long barId;
if (persistenceUnitUtil.isLoaded(foo, "bar") {
    barId = foo.getBar().getId();
} else {
    barId = persistenceUnitUtil.getId(foo, "bar");
}

Note that the if/else is just for the example here. PersistenceUnitUtil#getId should be able to grab the Id of a given relation independent of its loaded status.

An alternative would be to explicitly map an extra instance field in Foo to the FK column in the table to which Foo is mapped, and then use a proprietary "read only" annotation, e.g.

@Entity
public class Foo {

    @Id
    Long id;

    @OneToOne(fetch = LAZY)
    Bar bar;

    @Column(name = "bar_id")
    @ReadOnly // made-up proprietary annotation, but many providers have something like this
    Long barId;

    // + getters/setters
}

I've seen this workaround actually being used in practice, but it's not so nice of course.

Comment by c.beikov [ 15/Apr/14 ]

@arjan: Which persistence provider are you using? In hibernate this is no problem and I also don't see why other persistence providers would load the entity just because you access the id. I don't know if the spec says anything about the behavior in that case but it would definitely be nice for portability reasons to have a defined behavior.





[JPA_SPEC-58] script generation : same table name, different schema are merged Created: 15/May/13  Updated: 15/May/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: laps Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows : XP SP3
Glassfish : Oracle GlassFish Server 3.1.2.2 (build 5)
Eclipse : Indigo Build id: 20110615-0604
JRE : jdk1.6.0_33


Tags: create, ddl, eclipselink, generate, script, table

 Description   

Write two entities with the same table name but different schema :

@Entity
@Table(name="tablename", schema="schema1")
public class MyEntitySchema1 {
}

@Entity
@Table(name="tablename", schema="schema2")
public class MyEntitySchema2 {
}

Configure persistence.xml like this :
...
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="sql-script"/>
<property name="eclipselink.create-ddl-jdbc-file-name" value="create.sql"/>
<property name="eclipselink.drop-ddl-jdbc-file-name" value="drop.sql"/>
...
</properties>
...

And then check the generated script create.sql :
CREATE TABLE schema2.tablename (...)
ALTER TABLE schema2.tablename ADD CONSTRAINT ...

Nothing about schema1.tablename in the script file.

If I change one thing (ex. update a letter of tablename from lowercase to uppercase, I get both tables generated. (Those tables already exist, so this is not a solution for me).






[JPA_SPEC-55] Add variant of EntityManager#merge that modifies argument instead of returning new instance Created: 22/Apr/13  Updated: 14/Jan/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: arjan tijms Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The EntityManager's persist method modifies its argument (the entity to be persisted) with generated data such as the Id.

The merge method can also be used to persist a new entity, but has the additional benefit that it can also update the entity or any of its relations in the DB. merge however does not modify its argument but returns a new instance in which the generated data such as the Id is set.

For some uses cases its needed to have the original entity instance be modified such as the persist method does, but with the semantics of the merge method.

For instance, in a JSF application an existing (persistent but detached) entity is passed into an action method to add a new entity into e.g. a @OneToMany relation. When the action method returns, rendering of the page begins, which still has a reference to the original entity. Depending on the backing bean and template structure of the page in question, it might not be trivial to have the action method replace this original reference that was passed into it, and the kind of update that persist does would be far more convenient.

For this I would like to request adding a variant of EntityManager#merge that modifies its argument instead of returning a new instance.

Alternatively a refresh method that accepts detached entities could also work for the above mentioned use case. Yet another alternative might be having an attach method that makes its argument attached, overwriting fields in that argument if an entity with the same identity happened to be present in the persistence context, but contrary to merge not updating any data in the database.



 Comments   
Comment by ymajoros [ 14/Jan/15 ]

What if you end up having multiple instances referring to the same row in database? They would all end up in PC??

If you do this in JSF, you really need to use the returned entity. If you can't do that, you have an architecture problem anyway.

persist() returns the same entity because it's new, and this guaranteed to be unique. You can't do that with updates.

Just curious: I don't really get your description of an attach() method that wouldn't update the database. Why would you want to have it managed by PC, but not updating the database? This is quite contrary to the basic ideas of JPA. Or am I missing something in your explanations?





[JPA_SPEC-54] Clarify behavior of RESOURCE_LOCAL EMF instantiated by container Created: 12/Apr/13  Updated: 12/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: Mitesh Meswani Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It is possible to inject/lookup an EMF that is derived from a RESOURCE_LOCAL pu. For such EMFs, we need to clarify the behavior for following:

1. Should we disallow specifying jta-data-source

2. If the persistence.xml specifies both non-jta-datasource and javax.persistence.jdbc.* properties, which one should take precedence?

3. If the persitence.xml specifies no database connection information, should we default non-jta-datasource?

3. If the persistence.xml just specifies javax.persitsence.jdbc.* properties, what should be the behavior? Should we still default non-jta-datasource






[JPA_SPEC-41] @Target Declaration for @Embedded Created: 17/Dec/12  Updated: 11/Apr/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: mquasten Assignee: ldemichiel
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Using an @Embedded inside an entity or an other Embedded isn't posible using an Interface for the Declaration of the field.

@Entity(name="NaturalPerson")
public class NaturalPersonImpl implements NaturalPerson{

@Column(length=50)
private final String firstname;

@Column(length=50)
private final String lastname;

@Embedded
@Target(NativityImpl.class) // This annotation is a hibernate Annotation, not a JPA Annotation, it shoud be take over in JPA
private final Nativity nativity;

public NaturalPersonImpl(final String firstname, final String lastname, final Nativity nativity)

{ this.firstname=firstname; this.lastname=lastname this.nativity=nativity; }

...
}

...

entityManager.persist(new NaturalPersonImpl("Kylie", "Minogue", new NativityImpl("Melborne", new GregorianCalendar(1968, 4, 28).getTime( ) );

Instead of the @Target (as it is done in native Hibernate) something like @Embedded(target=NativityImpl.class) is posible too (as it is done for the normal Relations @OneToMany, @ManyToOne , @ManyToMany

HardCoding the Implementation is bad, because Mocking with Mockito, EasyMock and so on is limited, when the implementations use final for example. Using the Hibernate Annotations avoid exchange interchangeability of the persistence provider. Specifieng abstract Classes in the target definition may me not possible, because the type can not be resoved reading the values back from database (because it isn't defined like by entities where the implementation is stored in the database). But simple cases without polymorhism should be possible.



 Comments   
Comment by Paul Benedict [ 11/Apr/14 ]

I agree with the analysis that adding @Embedded(target=...) would be better than a new annotation. It aligns nicely with @Column(targetEntity=...)





[JPA_SPEC-39] Clarify requirements on polymorphic associations Created: 21/Sep/12  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: w_c_smith Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The 2.0 specification states in 2.9 that "Relationships are polymorphic", but there exists one case that appears to be completely valid JPA that Hibernate explicitly does not support. The specification should explicitly state whether a provider is required to support this case.

When using a joined or single-table inheritance strategy, it is a common occurrence that an entity (e.g., Order) has a ManyToOne relationship with another entity (e.g., Customer). Since JPA supports class inheritance, it is possible that some of the Order instances are actually instances of a subclass (SpecialOrder), and we might want to have a Collection of just the SpecialOrder s on the Customer entity. (This is especially likely if Order is abstract and we want relationships directly to the subclasses.) An example class hierarchy looks like this:

@Entity
public class Customer {
  @OneToMany(mappedBy = "customer")
  private Set<SpecialOrder> specialOrders;

  @OneToMany(mappedBy = "customer")
  private Set<RegularOrder> regularOrders;
}

@Entity
public abstract class AbstractOrder {
  @ManyToOne
  private Customer customer;
}

@Entity
public class SpecialOrder extends AbstractOrder {
  private Date shippingDate;
}

@Entity
public class RegularOrder extends AbstractOrder {
  private Integer storeNumber;
}

The specification appears to imply but does not explicitly state that this arrangement is valid, while Hibernate explicitly requires that the mappedBy property be physically present on the exact class specified in the relationship mapping, not inherited from a superclass. This mismatch has inspired a surprising number of "how-to-work-around" blog posts and should be explicitly resolved for the next version of the specification.






[JPA_SPEC-34] Add support for JSR303 (Bean validation) annotations. Created: 18/Jul/12  Updated: 15/Apr/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: velobr Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: RFE

 Description   

Right now, JPA spec neglect Bean Validation annotations.

The way it is now we end with duplicated information:

    @Column(nullable = false, length = 200)
    @NotNull
    @Size(min = 4, max = 200)
    private String name;

Would be nice just do:

    @Column
    @NotNull
    @Size(min = 4, max = 200)
    private String name;

and end with same result.



 Comments   
Comment by ldemichiel [ 10/Dec/12 ]

Actually, result is not the same, because Bean Validation will trap the constraint validation before it goes to the database. I think what you may be asking for is integration of Bean Validation constraints into the schema generation facility. There has not been strong support for this, but it is something that we could consider in a future release.

Comment by c.beikov [ 15/Apr/14 ]

I think that this is also related to JPA_SPEC-23
If a "PhysicalCustomizer" as mentioned in the comments could alter the column definition we could even translate annotations to domain constraints by ourselves. I guess what we really need here is an abstraction that enables us to enrich the meta- and physical model in general.





[JPA_SPEC-35] Support for more Java types Created: 06/Aug/12  Updated: 20/Mar/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mkarg Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JPA currently only supports few Java types to be persisted, mostly generic types, Strings and Date. Since many applications would benefit from it, support for direct persistence of java.net.URL (as VARCHAR) and java.awt.Image (as BLOB) should be added. Both are commonly used in many applications and currently produce an overhead of manually written code when to be used in JPA entities.

In addition (or as a replacement for the above), it would be great to have the possibility to map any not supported Java type to any kind of supported Java type, in analogy to the XmlAdapters used in JAXB marshall / unmarshall. This would relax the need for special support for Image and URL. As an example how this could work, please look at the following pseudo-code, which demonstrates how java.net.URL could get marshalled to a String at time of persisting it:

@Column(name = "MY_SQL_FIELD_NAME"
@JpaAdapter(UrlJpaAdapter.class)
private URL someField;
...
public class UrlJpaAdapter.class extends JpaAdapter<String, URL> {
public URL unmarshal(String v) throws MalformedURLException

{ return new URL(v); }

public String marshal(URL v)

{ return v.toString(); }

}



 Comments   
Comment by sinuhepop [ 05/Nov/12 ]

I agree. This is a very common need and must be placed in JPA standard.

But I think it will be too verbose to put always the same annotation n the same types. Maybe is better to use a TypeRegistry:

TypeRegistry registry = entityManagerFactory.getTypeRegistry();
registry.register(URL.class, new UrlJpaAdapter());

Comment by neilstockton [ 20/Mar/15 ]

Alternatively, allow JPA implementations to support as many field types as they want to, and provide method(s) on ProviderUtil that returns the types that are supported, or whether a type is supported.

JPA could also just link in to the AttributeConverter facility, and a JPA implementation could find what converters are available in the CLASSPATH (and hence has support for them). Hence if a library provider wants their types automatically supported in all JPA implementations they just provide AttributeConverters ...





[JPA_SPEC-32] Add a property to define cache implementation in persistence.xml Created: 27/May/12  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: cache, configuration, jpa, persistence

 Description   

The cache implementation for the second level cache currently has to be configured via vendor specific properties but the semantics of the Cache are already reflected in the interface javax.persistence.Cache. The cache implementation should be configurable via persistence.xml.

I propose the property javax.persistence.cache.provider and the value of it should be the class name of the cache provider that actually implements javax.persistence.CacheProvider.

The CacheProvider interface could look similar to the RegionFactory interface hibernate actually uses.
Including the option to specify cache implementations in a stadardized way will improve the portability of applications and also make people to use the standard JPA provider of a container instead of packaging their own one in their applications.



 Comments   
Comment by arjan tijms [ 08/Nov/12 ]

Maybe it's also convenient to take JCache into account, instead of or perhaps next to a new javax.persistence.CacheProvider? Just like JPA 2.1, JCache is slated for inclusion into Java EE 7.

Comment by c.beikov [ 09/Nov/12 ]

I wasn't aware of the status of JCache back when I made this issue. Integrating JCache is IMHO the right way!





[JPA_SPEC-29] Constructing a CriteriaQuery from a Query Created: 24/May/12  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: arjan tijms Assignee: ldemichiel
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: JPA_next, criteria, jpql, query

 Description   

In JPA 2 a query can be defined in JPQL for which a Query instance can be constructed, or via a Criteria for which a CriteriaQuery can be build. Via the EntityManager, a Query can be created from a CriteriaQuery.

However, it's not possible to create a CriteriaQuery from a Query. This would be particular useful for those use cases where a base query is written in the arguably more readable JPQL, which can then be transformed to a Criteria such that (small) modifications can be made to it programmatically. Such modifications could e.g. be adding an extra condition in an existing WHERE clause, adding an ORDER BY clause, etc.

I would like to request to add this capability.



 Comments   
Comment by ldemichiel [ 22/Feb/13 ]

Being able to map back and forth between CriteriaQueries and JPQL queries would be useful to have. This is something that should be considered in a future release.





[JPA_SPEC-17] Dynamic persistence unit Created: 01/Apr/12  Updated: 11/Nov/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: likenootherufo Assignee: ldemichiel
Resolution: Unresolved Votes: 8
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: JavaEE, dynamicaly, persistence

 Description   

Without changing code and redeploying my application, I need to be able to switch persistence units in some of my EJBs based on client connected to system.
It is similar to multitenancy, but whereas there a single DB is divided into equal shares and shared between multiple tenants, here a single tenant wants multiple DBs appearing as a single one.
During runtime based on the client connected to the EJB, the specific database should be selected.
Currently I achieve this using JDBC connections and just changing the database connection details based on client connected.
The database connection details are stored in the main system database and retrieved when the client connects.
This allows the system to grow with ease as new client databases can be created on the fly and simply linked to the client
in the database.
Ideally I would like to dynamically add new persistence units to the system (persistence.xml) and then in my database
link these persistence units to a given client. When the client connects, the system loads the required persistence unit.



 Comments   
Comment by ldemichiel [ 22/Feb/13 ]

I think you are really asking for multitenancy support in Java EE, which is something that we don't yet support. This is a candidate item for Java EE 8, at which point we should revisit this issue for JPA.

Comment by c.beikov [ 24/Apr/13 ]

This would be something really nice to have but I also think that this is already possible.
You coud have e.g. a CDI producer for the EntityManager which returns a proxy that is actually capable of that switching.
This is really nice, I think I will implement this in my application too

public class EnvironmentAwareEntityManager implements EntityManager {

  @Inject
  @Any
  private Instance<EntityManager> ems;

  private EntityManager select(){
    for(EntityManager em : ems) {
      if(!(em instanceof EnvironmentAwareEntityManager)) {
        // Do your selection based on your needs
      }
    }
  }

  // ... delegate all calls to the result of select()
}
Comment by arjan tijms [ 24/Apr/13 ]

@c.beikov

With that method, how would you actually add a new persistence unit at runtime, or alternatively let an existing persistence unit point to a different database?

Comment by c.beikov [ 24/Apr/13 ]

Adding a new persistence unit is kind of tricky with the current state of the API. This is currently only possible my managing the EMFs within the application but you probably also have to depend on some code of the underlying persistence provider to do the dynamic configuration of the EMF. Transaction Management and so on could be handeled by using the new transaction interceptors of Java EE 7(at least I think that it would be possible, not sure about that). It is possible but not entirely with the standards provided by JPA.

The requirement was to switch PUs but not the underlying datasource of a PU. So when you know at deployment time what PUs you have you can do it like that.

I could still think of something else, but this is probably the worst solution. You could set a comment hint on every query you execute, let the address of the PUs database point to a proxy that does the selection by inspecting the comments.

Comment by jbsmathers [ 11/Nov/13 ]

This would allow the end user to make new db connections, and that would add a variety of functionalities not currently available in jee without redeployment. I have wondered about this since JEE5 and unless there are excellent reasons not to do it, I hope its in jee8.





[JPA_SPEC-21] enable Serialisation of Entities Created: 10/May/12  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Mark Struberg Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: JPA_next

 Description   

Currently a JPA provider cannot guarantee that Entities are serializable since it is always possible that the entity is pessimistically locked (select for update).

The other problem is that JPA entities (per spec) loose all the state of lazy loaded fields and their dirty tracking information on serialisation. The result is that you basically cannot use them for any web application. Even if most EE6 samples use entities directly in their backing beans this does not work in practice (if you do not use non-spec conform magic switches) if clustering kicks in or you use e.g. the JSF ViewMap to store your entities.

The JPA spec currently states that you can either use lazy loading or serialisation. But this is impracticable. Not being Serializable means that you cannot use Entities in a webapp. Not having LazyLoading means that you will end up with 'database spaghetti' (pulling one entity and materializing half the database).

A possible solution:

step A:

/**
 * This one only allows optimistic operations and will throw an Exception on pessimistic ones.
 * It can be created via EntityManagerFactory#createOptimisticEntityManager()
 */
public interface OptimisticEntityManager extends EntityManager, Serializable {}

step B:

force that each @Entity produced via this OptimisticEntityManager must explicitly declare the following fields:

  • @Id and @Version. Otherwise you cannot do optimistic locking properly after serialisation.
  • a state field [1] to serialize all information needed to track dirty fields and lazy loading information even after serialisation.

[1] I'm not yet sure how to implement this best. OpenJPA and EclipseLink already store all the state in the enriched/enhanced/weaved entity. The problem is just that they need to be switched to a mode where they do not only serialize the native entity but also all additionally needed info as well.
Since Hibernate stores all this information in the EntityManager (and not in the Entity), we need to spare some field in the Entity which will get filled when the entity gets detached.

One way would be to introduce a new field of type javax.persistence.State which must always be available in Serializable entities used by an OptimisticEntityManager. Of course this field never gets persisted to the db.

Any other ideas and spec clarifications (if I misunderstood something) is highly welcome!



 Comments   
Comment by mkeith [ 15/May/12 ]

We have actually spent a great of time discussing variants of this problem since the first release of JPA, and there are a few possible solutions to the problem, but because of differing vendor opinions, implementations, and philosophies we have not yet reached a satisfactory conclusion. Unfortunately it is doubtful we will be able to do so in this release, either.

Comment by Mark Struberg [ 20/May/12 ]

Hi Mike!

Thanks for the honest answer. As I am EG member on other JSR myself, I certainly know those 'games'. This special issue has indeed a long history. I've seen EJB bug reports from 2005 (or even older?) which are originated in this very problem. And they all got bulk-updated and set to closed WITHOUT solving the underlying problem.

But all this doesn't change the fact that this is still broken and users don't care about political games behind the scene. This is really one of the reasons why user turn away from JPA and use SpringData, iBatis and eBean instead.

Currently the only way you can work with JPA in big projects is the old EJB transaction pattern where all entities get detached after the service invocation and NOT get used anymore in JSF pages or even JSF backing beans. But exactly that is what most EE6 samples currently showcase - despite being broken. This also renders JSR-303 mostly useless. Really, the only way to use JPA in a web app atm is to only use DAOs in the view layer and doing optimistic locking detects manually. This just sucks.

As for the JPA vendors:
I'm pretty sure that JBoss is interested to fix this. Especially since they heavily promote the entitymanager-per-conversation pattern which would then start to work.
I'm OpenJPA committer myself, and I think this will also be welcome in our community.
I've not much clue about EclipseLink, but as they afaik also store the state inside the Entities it should also be doable.

Are there any other JPA vendors which are active in the JSR or have a bigger community?

Comment by ldemichiel [ 22/Feb/13 ]

Well, we tried to resolve this via a proposal based on entity graphs, but could not achieve closure. This is something that we should revisit in JPA.next.





[JPA_SPEC-25] Add support to retrieve JPQL query from Query object Created: 24/May/12  Updated: 25/Jun/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: c.beikov Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: JPA_next, jpql, query

 Description   

Currently the interfaces javax.persistence.criteria.AbstractQuery and javax.persistence.Query have no support for retrieving the underlying JPQL Query for additional transformation which would be, especially for named queries, very useful! Just think of the fact, that you currently have to copy and paste a named query if you like to have exactly the same query with an additional predicate in the where clause. The predicate in the where clause is just an example, there are probably tons of use cases where this feature would be helpful and minimize redundant code!

I would suggest to add the following methods:

Query.java
public interface Query{
  // currently available methods...

  public String getQuery();
}
AbstractQuery.java
public interface AbstractQuery{
  // currently available methods...

  public String getQuery();
}


 Comments   
Comment by Antonio Goncalves [ 25/May/12 ]

As I wrote on my blog (http://agoncal.wordpress.com/2012/05/24/how-to-get-the-jpqlsql-string-from-a-criteriaquery-in-jpa/), having the JPQL String representation of a CriteriaQuery is very useful for debugging purpose. And going further, having the SQL String would also be useful. I would go for :

public interface Query {

  public String getJPQLQuery();
  public String getSQLQuery();

}
Comment by ldemichiel [ 22/Feb/13 ]

Being able to map back and forth between CriteriaQueries and JPQL queries would be useful to have. This is something that should be considered in a future release. See also http://java.net/jira/browse/JPA_SPEC-29

Comment by arjan tijms [ 22/Jun/15 ]

Just wondering if this is still considered, specifically for Java EE 8 (for which no JPA EG has been formed as of now).

In the 3 years since this issue has been created the lack of this feature impedes my work on almost a daily basis. In particular it makes paging/sorting from services quite difficult and obscure.

Comment by neilstockton [ 24/Jun/15 ]

+1 but I would suggest that the method to return the (SQL) native query is actually

String getNativeQuery();

which then aligns with how "SQL" is accessible in the query API.

Comment by arjan tijms [ 25/Jun/15 ]

I wrote an article about this issue and described how to do this when using Hibernate. See http://jdevelopment.nl/counting-rows-returned-jpa-query

Ideally something like would be standardized. Note that just String getNativeQuery() is not really enough. Some info about the translated query parameters is also needed.





Support for more automatic values besides @GeneratedId (JPA_SPEC-36)

[JPA_SPEC-51] @PrePersist / @PreUpdate / @PostPersist / @PostUpdate Created: 23/Feb/13  Updated: 23/Feb/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

New annotations "@PrePersist" / "@PreUpdate" / "@PostPersists" / "@PostUpdate" annotations are used to define the event when the above annotations are to be injected.

@PrePersist will be the most typical use case.

Example:

@PrePersist @CurrentUser String createdBy; // Injects who created this record.
@PrePersist @CurrentTimestamp Date createdOn; // Injects when this record was created.
@PreUpdate @CurrentUser String lastUpdatedBy; // Injects who last updated this record.
@PreUpdate @CurrentTimestamp Date lastUpdatedOn; // Injects when this record was last updated.






Support for more automatic values besides @GeneratedId (JPA_SPEC-36)

[JPA_SPEC-50] @QuerySingleResult Created: 23/Feb/13  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: mkarg Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

New annotation "@QuerySingleResult(ejbql = "JPAQL QUERY" | namedQuery = "name of query")" should inject the .getSingleResult() output of either a given JPAQL query or of a named query into a field annotated with this annotation.

This is often needed in business applications, for example if the written data is dependend of a aggregate other entities. This is what a trigger would do in databases.



 Comments   
Comment by ldemichiel [ 05/Apr/13 ]

It seems more flexible to me to do this with a producer method.

Comment by mkarg [ 05/Apr/13 ]

While I agree that this solution is not the most flexible one, it possibly opens the most pragmatic solution, as it implies least code to write for the application developer (just one single line naming the query to invoke), offloads as much as possible to lower levers (as the query does all the work on the database server and just transports a single result value over the possibly slow line), and is rather intuitive as it mimics mosty the idea of an INSERT or UPDATE trigger which sets a single value by invoking an aggregating SELECT (like defaulting to the Count of existing rows etc.).

A producer method might be more flexible, but it is not so pragmatic in the daily use, as it implies much more code to write in turn for a flexibility that might not be needed (several lines of code), does not offload by default (depends on the cleverness of the developer, hence, does neither guide nor support him), and is not very intuitive (demands knowledge of a rather complex API instead of simple tagging a field and looking at the IDE's code completion proposals).

So my proposal would be to have both ways and let the developer decide. For daily use the annotation is best. For complex and seldom cases Producer methods are best. I do not see that it is a general, mutual-exclusive API decision, but a use-case driven API usage decision.





Support for more automatic values besides @GeneratedId (JPA_SPEC-36)

[JPA_SPEC-49] @CurrentTimestamp Created: 23/Feb/13  Updated: 25/Nov/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: mkarg Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

New annotation "@CurrentTimestamp" should inject the current timestamp of a transaction into a data field.

The annotation will guarantee that at the transaction start the timestamp is produced once, so all uses of the annotation within the same transaction will guarantee to inject the same timestamp value.

This is another essential business need, as sometimes transactions run rather long, but all written data shall have synchronized timestamps.



 Comments   
Comment by rbygrave [ 24/Nov/16 ]

Personally I'd argue for 2 annotations like @WhenCreated and @WhenUpdate. I've already mentioned this in #48 wrt SQL2011 History support and auditing etc. Just adding this comment here in case ... something happens !!

Comment by neilstockton [ 25/Nov/16 ]

+1 for @CreateTimestamp and @UpdateTimestamp, and with both taking the timestamp at FLUSH. The reason to use flush timestamp is that with updates you may have multiple updates of an object in a transaction, so need to distinguish which update.





Support for more automatic values besides @GeneratedId (JPA_SPEC-36)

[JPA_SPEC-48] @CurrentUser Created: 23/Feb/13  Updated: 24/Nov/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Sub-task Priority: Major
Reporter: mkarg Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

New annotation "@CurrentUser" should inject the current user into a data field (this is what databases do with the CURRENT USER constraint).

As in the Java EE environment there is a difference between security principals, business layer people, and database accounts, there should be a mapping available. For example "@CurrentUser(type = PRINCIPAL_NAME) String createdBy" would default the content of "createdBy" to the name of the caller principal's name. This is the most common need for automatic values in business applications.



 Comments   
Comment by arjan tijms [ 22/Apr/13 ]

I wonder if something akin to @CurrentUser should not also, or perhaps first, be available for the entire Java EE platform.

Comment by mkarg [ 22/Apr/14 ]

Arjan, you can inject the current security principal into any CDI beand and EJB. So you have that there already. My proposal is focused on JPA because you cannot inject the security principal into a JPA entity.

Comment by rbygrave [ 30/Jun/16 ]

I don't think @CurrentUser is sufficient. That is, I think it is more common from an auditing perspective to require "who created" and "who modified" so instead have 2 annotations like:
@WhoCreated
@WhoModified

Background:
These are the 2 annotations that we have in Ebean ORM which also has support for SQL 2011 history / temporal features ... "AS OF" queries and "BETWEEN VERSIONS" queries. Having both the user who created a row/object and user who last modified the row/object is not absolutely required once you have full SQL 2011 history support but I'd suggest it is a fairly common requirement otherwise. (So commonly there are 4 properties - @WhoCreated, @WhoModified, @WhenCreated, @WhenModified)

Comment by neilstockton [ 24/Nov/16 ]

How does a plain JPA provider know what is the "current user"? In JavaSE there is no "user". Define where this is populated from

Comment by rbygrave [ 24/Nov/16 ]

> now what is the "current user"?

There would also be an interface that is implemented (and registered with the JPA provider / EntityManagerFactory).

For me this looks like:

/**
 * Provides the current user in order to support 'Who created', 'Who modified' and other audit features.
 */
public interface CurrentUserProvider {

  /**
   * Return the current user id.
   * <p>
   * The type returned should match the type of the properties annotated
   * with @WhoCreated and @WhoModified. These are typically String, Long or UUID.
   * </p>
   */
  Object currentUser();
}
Comment by rbygrave [ 24/Nov/16 ]

As a side node, I'd expect that Multi-Tenancy would need a similar CurrentTenantProvider interface.





[JPA_SPEC-47] Usability of @Enumerated and @MapKeyEnumerated Created: 11/Feb/13  Updated: 20/May/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: jd3714att Assignee: ldemichiel
Resolution: Unresolved Votes: 9
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: enum, jpa

 Description   

In mapping a pre-existing schema, it is rarely possible to map a given set of constants using an @Enumerated:

  • Ordinals are non-sequential
  • Names are incompatible with Java Enum Constants
  • Names cannot be aliased to something more useful or conventional for Java Naming standards

Limitation is because specification states the name() will be used of an enum.
A typical example: Database uses 'N/A', which can never be mapped to an enum. Intuition will let us look for a solution to map this to 'NOT_AVAILABLE', both a valid name for an Enum Constant, and also conventional naming.

On top of this, an enum often has a representation in the Database, and a constant has usually other additional attributes that could be useful.
Better than using the name() of an @Enumerated, we should map the enumerated similar as an @Entity, and use the @ID.



 Comments   
Comment by jd3714att [ 26/Nov/14 ]

Would this not be more elegant than using a @Converter to solve the problem.

@Enumerated
public enum Language {
  ENGLISH_US("en-US"),
  ENGLISH_BRITISH("en-BR"),
  FRENCH("fr"),
  FRENCH_CANADIAN("fr-CA");
  @ID
  private String code;
  @Column(name="DESCRIPTION")
  private String description;

  Language(String code) {
    this.code = code;
  }
  
  public String getCode() {
    return code;
  }

  public String getDescription() {
    return description;
  }
}
Comment by HajoLemcke [ 16/Dec/14 ]

This looks great. And it would solve the problem to have a separate converter for each enumeration because a generic converter can not be build type save.

Comment by rbygrave [ 28/Apr/15 ]

I don't think @Column(name="DESCRIPTION") is required. The only requirement is to mark the field (as you have done with @ID) or mark a getter method that returns the value to be stored in the DB.

So instead annotate the getCode() method like:

@DbValue
public String getCode() { return code; }

or

@Id
public String getCode() { return code; }

Another alternative would be to create an annotation that acts just like @XmlEnumValue does for xml mapping ... so create a @DbEnumValue such that:

@Enumerated
public enum Language {
  @DbEnumValue("en-US")
  ENGLISH_US,
  
  @DbEnumValue("en-BR")
  ENGLISH_BRITISH,

  @DbEnumValue("fr")
  FRENCH,

  @DbEnumValue("fr-CA")
  FRENCH_CANADIAN;
Comment by pbenedict [ 23/Nov/15 ]

This kind of custom transformation can now be expressed with Converters. I've done it myself for several situations. Converters, not enums that transform themselves into a DB value, is the correct way to separate out model code from integration code.

Comment by rbygrave [ 23/Nov/15 ]

> Converters, not enums that transform ...
For me I'd say its a balance between pragmatism and 'purity'. The @DbValue annotation on a method approach mirrors a similar approach Jackson takes for JSON and personally I think it represents significantly less work than writing a Converter. So yes, I'll agree to disagree with you there on pragmatism over purity grounds.

Comment by pbenedict [ 23/Nov/15 ]

Yes, it is less work. The approach you mention I have used for many years; finally turned away from it for several reasons. It began to breakdown the moment I had many ways of encoding an Enum for multiple systems: perhaps an existing database requires code XYZ but a new technology requires code ABC. All those things are possible which is why I think the "purity" aspect (integration code) is a better design because it frees you up from coupling concerns.

Comment by pbenedict [ 23/Nov/15 ]

In closing, I should mention that you could create a nearly-universal Enum-to-String attribute converter that accomplishes your reusability requirements. You already have the value in your example code; just move it into the enum constructor; provide a standard interface that exposes the code; finally do the conversion in the Converter.

Example:

public interface Coded {
  String code();
}

@Enumerated
public enum Language implements Coded {
  ENGLISH_US("en-US"),
  ENGLISH_BRITISH("en-BR"),
  FRENCH("fr"),
  FRENCH_CANADIAN("fr-CA");

  private String code;

  private Language(String code) {
      this.code = code;
  }

  // To database: converter uses this
  // From database: converter loops values() and compares DB column against code()  
  public String code() { return code; }
}

// Reusable universal logic to convert back and forth
public abstract class YourAbstractCodedConverter<X extends Enum<X> & Coded> implements AttributeConverter<X,String> { 
}

// Strongly typed for JPA
public class YourLocaleCodedConverter extends YourAbstractCodedConverter<Language> {
  // empty
}
Comment by pbenedict [ 24/Nov/15 ]

@rbygrave, I reverse my opinion. I went to demonstrate one thing and have concluded another. After writing out the code above, it's clear the code is boilerplate and more complex than is necessary. Thus, I now support this ticket and have voted it up. This should be allowed via an annotation.

The pattern above clearly keeps out the integration (JPA) from the model code. This is very important when the Enum is part of a public API (where no such dependency should be required), but this is not always everyone's goal. Sometimes Enums are dedicated to JPA ... or, as you said, you don't prefer to keep such a "pure" separation of concerns.

Comment by jd3714att [ 24/Nov/15 ]

@pbenedict, in regards to "pure" separation of concerns, who says that separation is not there? We only have Java Identifier (the enum instances) vs Internal Code, which neither has to be the actual vendor specific backing presentation. That separation should still be possible, although this is not what I intended. So to that regards I would also avoid using names that include "Xml", or "Db".

Comment by rbygrave [ 01/Mar/16 ]

FYI

Just for information purposes I have implemented this in my ORM.

All that is required is to annotate the method used to return the value stored in the database (the getCode() method in the example below). For my ORM I use @DbEnumValue. The ORM loops the enum entries and builds its map of DB to Enum values to there is no need for anything else (no other annotations required etc).

The original example becomes:


public enum Language {

  ENGLISH_US("en-US"),
  ENGLISH_BRITISH("en-BR"),
  FRENCH("fr"),
  FRENCH_CANADIAN("fr-CA");

  private String code;

  Language(String code) {
    this.code = code;
  }

  @DbEnumValue  
  public String getCode() {
    return code;
  }

}

Note: The @DbEnumValue annotation has a storage() attribute that can be either DbEnumType.VARCHAR or DbEnumType.INTEGER.

Cheers, Rob.

Comment by jaguild [ 16/Mar/16 ]

Work in this area just cannot happen fast enough; this is a huge omission even when you do control the schema.

Our schemas tend to have FK constraints from data tables to "enum" tables that contain fixed control data. I don't even care if we have to write some boilerplate in the style that @pbenedict suggested above...that seems OK to me, but I'd like to add that any improvements to enum support should allow mapping an enum to these kinds of dedicated control data tables:

@Enumerated(table="LANGUAGE_TYPE")
public enum Language implements Coded {
  ENGLISH_US("en-US"),
  ENGLISH_BRITISH("en-BR"),
  FRENCH("fr"),
  FRENCH_CANADIAN("fr-CA");

  @EnumeratedColumn(name="code")
  private String code;

  private Language(String code) {
      this.code = code;
  }

  // To database: converter uses this
  // From database: converter loops values() and compares DB column against code()  
  public String code() { return code; }
}

This still requires us to duplicate the control data values in the table as enum constants and keep the two in sync, but at least it gives us the strong typing of values found in the LANGUAGE_TYPE table. I think it could otherwise work like @pbenedict implies in his code sample.

What would be really awesome is if the JPA provider could scan the table on startup and somehow update the enum constant code values with the data from the @EnumeratedColumn to avoid having to duplicate and hardcode the same values from the database table into in the Java enum type itself. I don't know if that last idea is possible due to how enum types are implemented in the first place.

But, the provider could at least maintain an internal map of enum type constants to actual rows on a default enum.getCode() == LANGUAGE_TYPE.code policy so FK column updates could occur correctly when an entity property that is mapped to an @Enumerated type is changed. Regarding a point made by @jd3714att in the original issue description, some kind of optional name mapper could be specified to provide a different matching policy allowing the provider to handle dealing with values found in the target table that violate Java enum constant naming rules.

Comment by neilstockton [ 27/Apr/16 ]

What if the enum is part of some other library? With the proposal the user would have no way of defining to persist something other than the ordinal/string even though methods may exist. Any "solution" needs to have an orm.xml alternative.

Comment by pbenedict [ 27/Apr/16 ]

Neil, see all my comments above in which I first objected to this feature. In my objection, I had such a use case in mind that is like yours. However, for those who actually own their enum and don't need that level of abstraction, which @rbygrave was pointing out, it is overkill.

Comment by neilstockton [ 20/May/16 ]

Well I still "object" (FWIW) because it is unlikely to happen in that way due to the fact that current enum persistence is specified in the class holding the enum via @Enumerated (and not on the enum).

To support persistence of return value of method (on the enum, like above examples) it easily doable to extend the current @Enumerated to add a new EnumType and add an attribute for the method name (on the enum that will be persisted). That way you also can have XML specification of the method to use (rather than the above that only work with annotations, and not everybody thinks that's a "good idea").

@Enumerated(value=EnumType.METHOD, methodName="getCode")
Language lang;





[JPA_SPEC-46] Explicitly allow or disallow use of Entity Manager with extended Persistence Context for CDI injection Created: 05/Feb/13  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: donatasc Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

CDI specification has so called producer methods, allowing to create (or retrieve) objects to be injected.

JPA specification should explicitly state whether is it allowed for Stateful Session bean to have a producer method that returns extended EntityManager?
For example, is this legal:

@ConversationScoped
@Stateful
public class MyConversationBean {
@PersistenceContext(type=EXTENDED)
private EntityManager em;

@Produces
public EntityManager getEntityManager()

{ return em; }


}

This would be useful if conversation is implemented with several session beans and they all want to share a single extended EntityManager.



 Comments   
Comment by ldemichiel [ 22/Feb/13 ]

I think this is probably more an EJB issue than a JPA one, but in any case
it is something that we should evaluate for the next release.





[JPA_SPEC-140] Add "value" property to common annotations Created: 22/Jan/17  Updated: 22/Jan/17

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: ggam Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There are some annotations where, usually, only one property is specified by users. Examples:

  • Table: usually only "name" is specified.
  • Entity: it has just one "name" property.
  • Column: when dealing with legacy schemas, only "name" is usually used.

In those cases, a "value" property could be added, that works in a similar fashion that @WebServlet uses with urlPatterns: if only value is specified, it is treated as if was the urlPatterns property. This allows to reduce verbosity a bit.

Take this entity as an example. From:

@Entity(name = "BlogPost")
@Table(name = "posts")
public class Post implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "post_id")
    private Long id;
    @Column(name = "post_title")
    private String title;
    @Column(name = "post_content")
    private String content;
}

To:

@Entity("BlogPost")
@Table("posts")
public class Post implements Serializable {

    @Id
    @GeneratedValue
    @Column("post_id")
    private Long id;
    @Column("post_title")
    private String title;
    @Column("post_content")
    private String content;
}

In case any other properties are defined, "value" is ignored, just like the Servlet spec does.






[JPA_SPEC-112] EntityGraph addAttributeNodes generic type incorrect Created: 07/Aug/15  Updated: 19/Jan/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: neilstockton Assignee: ldemichiel
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The method in EntityGraph (and EntitySubgraph)
public void addAttributeNodes(Attribute<T, ?>... attribute);

should be
public void addAttributeNodes(Attribute<? super T, ?>... attribute);

since we should be able to write code like this

EntityGraph<SubEntity> graph = em.createEntityGraph(SubEntity.class);
graph.addAttributeNodes(SubEntity_.baseEntityField);

yet currently it is a compiler error due to this generic type bug.

The same applies to other methods that refer to Attribute<T, ?>



 Comments   
Comment by neilstockton [ 19/Jan/16 ]

Perhaps this bug ought to be fixed in JPA 2.2 since it is trivial to do?





[JPA_SPEC-60] Upload official/standard JPA 2.1 API jar to Maven Central Created: 13/Jun/13  Updated: 09/Jan/17  Due: 22/May/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: Improvement Priority: Major
Reporter: Matthew Adams Assignee: Lukas Jungmann
Resolution: Unresolved Votes: 36
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: maven, osgi, repositories

 Description   

There is no official or standard JPA API jar available from the expert group in either Maven Central or the java.net Maven repo that both JPA users & implementors can utilize. Users are left to search for implementations' groupId, artifactId, & version values, which is inconvenient.

Please upload a binary jar (including class files and relevant resource files), a source jar, and a javadoc jar, under the groupId "javax.persistence", artifact id "jpa-api" and version "2.1". A minimal target Maven repository would be Maven Central, but others like java.net might be nice, too.

Bonus points for including OSGi bundle metadata (pretty easy if using Apache Felix's Maven Bundle Plugin, org.apache.felix:maven-bundle-plugin:2.3.7)!



 Comments   
Comment by Matthew Adams [ 13/Jun/13 ]

This issue is the same as https://java.net/jira/browse/JPA_SPEC-19 except for JPA 2.1.

Comment by datanucleus [ 13/Jun/13 ]

Since when has an implementation had to provide their own variant of the "standard" API jar? Such a basic thing ought to be a prerequisite of the JSR to have that as one of its deliverables and the JSR not considered "complete" til its done, just like the spec and TCK (and add to that publishing of XSD/DTDs on a public site). Or maybe its just another way to keep it all "secret" (like that mystical TCK) ...

Comment by Matthew Adams [ 13/Jun/13 ]

http://search.maven.org/#artifactdetails%7Cjavax%7Cjavaee-api%7C7.0%7Cjar

Is this intended to be the release? If so, it might do for some, but a standalone JPA API artifact would be ideal.

Comment by neilstockton [ 14/Nov/13 ]

Seems like voting on this JIRA is not looked at by the people behind JPA, evidently not interested in what the majority of people want.

Comment by Oliver Gierke [ 07/Feb/14 ]

I'd also like to vote to finally introduce a canonical API JAR. We're currently seeing a lot of users running into classpath issues for the following reasons:

Persistence providers historically shipped their own packaged API versions. For libraries trying to build on top of JPA this created the unfortunate situation that they had to refer to a persistence provider provided API JAR which subverts the provider independence of the library.

Even worse, as the providers get access to the API JARs in different versions they do not use the specification version as artifact version but incorporate the spec version in the artifact id. E.g. for Hibernate, the API JAR has the following coordinates:

2.0 - org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final
2.1 - org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final

Note, that these two do not represent a single artifact in different versions but two completely separate artifacts. Hence, dependency management systems will not be able to apply version conflict resolution to those and users are very likely to accidentally get both JARs into their classpath and then spend a lot of time debugging ClassNotFoundExceptions for their JPA 2.1 provider that might see the 2.0 JAR first.

Long story short, this is way more tedious than it needs to be. Releasing a canonical API JAR would solve these issues.

P.S.: No, a 1.8 MB JavaEE 7 API JAR is probably not what you want to pull into an application or library that depends on JPA only.

Comment by marcelstoer [ 05/Oct/15 ]

If the maintainers have no intention of fixing this they should at least close it with 'won't fix' - and ideally give an explanation why such an obvious "feature" isn't implemented.

Comment by mkarg [ 04/Apr/16 ]

It would be good if there would at least any sign of life from the specification maintainers... Hello, Lukas, are you at least reading these comments...?

Comment by bkahlerventer [ 09/Jan/17 ]

Maybe someone should implement this independently since Oracle appear to have abandoned J2EE, irrespective their public statements

Comment by neilstockton [ 09/Jan/17 ]

Maybe all major JPA 2.1 vendors (EclipseLink, Hibernate, DataNucleus) already have done that (which they have since their implementations cannot be used without such a jar) but that doesn't solve the issue. There should be an official standard jar

Comment by Lukas Jungmann [ 09/Jan/17 ]

When I raised this question in the past I got an answer that all providers are expected to provide their own implementation of the API and since majority of providers are already doing it, as Neil mentioned, I felt, maybe wrongly, push against creating standalone vendor neutral api jar. Another thing is that I've never got an answer to who owns 'javax.persistence' groupid in maven central so the artifact would follow the naming convention as I don't have enough permissions to just deploy the jar there (...and I'm not talking about possible legal/licensing issues if I'd just find some way around - IANAL).
It is also unlikely that it will change for already released 2.1.

For 2.2 this absolutely has to change - what I want to have is JDK9 ready 'java.persistence' module defined with no additional dependencies for other to use; for example current jpa api jar provided by eclipselink contains few osgi classes which are not useful for others...





[JPA_SPEC-63] JPA next should support Java 8 Date and Time types Created: 11/Aug/13  Updated: 07/Feb/17

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: Improvement Priority: Major
Reporter: Nick Williams Assignee: Unassigned
Resolution: Unresolved Votes: 56
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: date, date-time, java8, jsr-310, temporal, time

 Description   

Currently, JPA temporal fields are supported for the following data types: java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, and java.sql.Timestamp. java.sql.Date properties are always mapped to the JDBC methods getDate and setDate, and it is an error to specify the @javax.persistence.Temporal annotation for these types. The same is true of Time (mapped to getTIme and setTime) and Timestamp (mapped to getTimestamp and setTimestamp). Properties of type java.util.Date and Calendar must be annotated with @Temporal to specify the javax.persistence.TemporalType enum indicating which JDBC methods should be used for those properties.

Some vendors support other temporal types, such as Joda Time, but this is non-standard and should probably remain so since Joda Time isn't guaranteed to stay around (and, in fact, is likely to start ramping down with the release of Java 8).

JSR-310 as part of Java 8 specifies a new Date & Time API in the java.time package and sub-packages that supplants java.util.Date, Calendar, java.sql.Date, Time, Timestamp, and Joda Time. It is based off of the Joda Time API, but with enhancements and certain redesigns that the Joda Time founder/creator has said makes it superior to Joda Time.

JPA's existing rules for the currently-supported temporal types should remain largely unchanged. However, the specification should be added to in order to specify support for JSR-310. These are the proposed new rules I believe should be present in the JPA.next specification:

  • Properties of type java.time.Duration are treated as @javax.persistence.Basic fields. They automatically map to;
    • DURATION fields if the database vendor supports duration types;
    • DECIMAL-type fields storing the seconds before the decimal point and the nanoseconds after the decimal point;
    • INTEGER-type fields storing the seconds; and,
    • CHAR/VARCHAR-type fields storing the value in its ISO-8601 format (Duration#toString() and Duration#parse(CharSequence)).
  • Properties of type java.time.Period are treated as @Basic fields. They automatically map to:
    • PERIOD or DURATION fields if the database vendor supports period or duration types;
    • DECIMAL-type fields storing the seconds before the decimal point and the nanoseconds after the decimal point;
    • INTEGER-type fields storing the seconds; and,
    • CHAR/VARCHAR-type fields storing the value in its ISO-8601 format (Period#toString() and Period#parse(CharSequence)).
  • Properties of type java.time.Year are treated as @Basic fields. They automatically map to:
    • YEAR fields if the database vendor supports year types; and,
    • INTEGER/CHAR/VARCHAR-type fields storing the literal number/string value.
  • Properties of enum type java.time.Month are treated as special-case enum fields.
    • If the database field is a MONTH field (assuming the database vendor supports such types), it maps to this field.
    • If @javax.persistence.Enumerated is not present and the database field is an INTEGER-type field, it maps as the month number (NOT the ordinal) using int Month#getValue() and Month Month#of(int).
    • Otherwise, it falls back to standard enum mapping rules.
    • It is an error to annotate a Month property with @Enumerated if the database field is of type MONTH.
  • Properties of enum type java.time.DayOfWeek are treated as special-case enum fields.
    • If the database field is a DAY_OF_WEEK field (assuming the database vendor supports such types), it maps to this field.
    • If @Enumerated is not present and the database field is an INTEGER-type field, it maps as the day number (NOT the ordinal) using int DayOfWeek#getValue() and DayOfWeek DayOfWeek#of(int).
    • Otherwise, it falls back to standard enum mapping rules.
    • It is an error to annotate a DayOfWeek property with @Enumerated if the database field is of type DAY_OF_WEEK.
  • Properties of type java.time.YearMonth are treated as @Basic fields.
    • By default, they automatically map to:
      • YEARMONTH fields if the database vendor supports year-month types;
      • DATE and DATETIME fields storing the lowest day number that the database vendor supports and zero-time if applicable; and,
      • CHAR/VARCHAR-type fields storing the value in its ISO-8601 format (YearMonth#toString() and YearMonth#parse(CharSequence)).
    • The new @javax.persistence.YearMonthColumns annotation can map a YearMonth property to two database fields. A property annotated with this overrides the default mapping behavior. It is an error to mark properties of any other type with this annotation. The required @javax.persistence.Column-typed year attribute specifies the column that the year is stored in while the required @Column-typed month attribute specifies the column that the month is stored in. The year column follows the same default mapping rules as for Year types and the month column as for the Month enum. It is an error to specify @Column and @YearMonthColumns on the same property.
  • Properties of type java.time.MonthDay are treated as @Basic fields.
    • By default they automatically map to:
      • MONTHDAY fields if the database vendor supports month-day types;
      • DATE and DATETIME fields storing the lowest year number that the database vendor supports and zero-time if applicable; and,
      • CHAR/VARCHAR-type fields storing the value in its ISO-8601 format (MonthDay#toString() and MonthDay#parse(CharSequence).
    • The new @javax.persistence.MonthDayColumns annotation can map a MonthDay property to two database fields. A property annotated with this overrides the default mapping behavior. It is an error to mark properties of any other type with this annotation. The required @Column-typed month attribute specifies the column that the month is stored in while the required @Column-typed day attribute specifies the column that the day is stored in. The month column follows the same default mapping rules as for the Month enum and the day column automatically maps to INTEGER/CHAR/VARCHAR-type fields. It is an error to specify @Column and @MonthDayColumns on the same property.
  • Properties of type java.time.ZoneId are treated as @Basic fields. They automatically map to:
    • TIMEZONE fields if the database vendor supports time zone types (they never map to offset fields); and,
    • CHAR/VARCHAR-type fields storing the value in its ISO-8601 format (ZoneId#toString() and ZoneId#of(String)).
  • Properties of type java.time.ZoneOffset are treated as @Basic fields. They automatically map to:
    • OFFSET fields if the database vendor supports offset types (they never map to time zone fields); and,
    • CHAR/VARCHAR-type fields storing the value in its ISO-8601 format (ZoneOffset#toString() and ZoneOffset#of(String)).
  • Properties of types java.time.Instant, java.time.LocalDate, java.time.LocalTime, java.time.LocalDateTime, java.time.OffsetTime, java.time.OffsetDateTime, and java.time.ZonedDateTime are treated as temporal @Basic types that are mapped using the following rules:
    • LocalDate always maps as a date-only value. It is an error to mark a LocalDate property with the @Temporal annotation.
    • LocalTime and OffsetTime always map as time-only values. It is an error to mark a LocalTime or OffsetTime property with the @Temporal annotation.
    • Instant, LocalDateTime, OffsetDateTime, and ZonedDateTime map as timestamp values by default. You may mark a property of one of these types with @Temporal to specify a different strategy for persisting that property.
    • The new @javax.persistence.TemporalIncludeTimeZone annotation indicates that the offset in the OffsetTime or OffsetDateTime property or the time zone in the ZonedDateTime or Calendar property will be persisted with the value. Otherwise (if this is absent) the value is converted to the database server offset or time zone for persistence.
    • The new @javax.persistence.TemporalTimeZoneColumn(@Column value) annotation indicates a different column in which the time zone value is stored. It implies @TemporalIncludeTimeZone. It is required if @TemporalIncludeTimeZone is present but the database vendor does not support storing the time zone with the field data type. It is also required if @TemporalIncludeTimeZone is present but the JDBC driver in use is less than version 4.2 (a JDBC 4.2 driver is necessary to persist time zones and offsets with time/date-time values). The persistence rules for this column are the same as for ZoneId and ZoneOffset properties.
    • Properties of these types invoke the following special handling for JDBC driver versions before and after 4.2.
      • A JDBC driver is considered version 4.2 or better if java.sql.Driver#getMajorVersion() returns a number greater than 4, or it returns 4 and Driver#getMinorVersion() returns a number greater than 1. In the absence of a testable Driver instance, implementations may assume that the driver version is less than 4.2 if PreparedStatement#setObject(int, Object, SQLType) throws a SQLFeatureNotSupportedException.
      • If the JDBC driver is version 4.2 or newer, these seven types are persisted and retrieved as follows:
        • They are persisted with PreparedStatement#setObject(int, Object, SQLType) and retrieved with ResultSet#getObject(int, Class<?>) or ResultSet#getObject(String, Class<?>).
        • Time-only properties or TemporalType.TIME properties use a java.sql.SQLType of java.sql.JDBCType.TIME in the absence of @TemporalIncludeTimeZone or presence of @TemporalTimeZoneColumn. They use JDBCType.TIME_WITH_TIMEZONE in the presence of @TemporalIncludeTimeZone and absence of @TemporalTimeZoneColumn.
        • Date-only properties or TemporalType.DATE properties use a SQLType of JDBCType.DATE.
        • Date-and-time properties use a SQLType of JDBCType.TIMESTAMP in the absence of @TemporalIncludeTimeZone or presence of @TemporalTimeZoneColumn. They use JDBCType.TIMESTAMP_WITH_TIMEZONE in the presence of @TemporalIncludeTimeZone and absence of @TemporalTimeZoneColumn.
      • If the JDBC driver is version 4.1 or older, these seven types are persisted and retrieved as follows:
        • Time-only properties or TemporalType.TIME properties are automatically converted to and from Time and use the traditional setTime and getTime methods.
        • Date-only properties or TemporalType.DATE properties are automatically converted to and from java.sql.Date and use the traditional setDate and getDate methods.
        • Date-and-time properties are automatically converted to and from Timestamp and use the traditional setTimestamp and getTimestamp methods.
        • @TemporalTimeZoneColumn is required if @TemporalIncludeTimeZone is present.


 Comments   
Comment by Nick Williams [ 11/Aug/13 ]

To be clear, by "JPA.next" I mean JPA 2.2 unless 3.0 is next and there isn't going to be a 2.2. "Whatever is going to be in Java EE 8."

Comment by Nick Williams [ 11/Aug/13 ]

A few additional notes:

  • The reason for specifying the JDBC < 4.2 vs JDBC ≥ 4.2 behavior is that, even today, some JDBC driver vendors have still not fully implemented JDBC 4.0 (Java 6), let alone JDBC 4.1 (Java 7). Unfortunately and terribly, it could be 5 or even 10 years before all driver vendors have JDBC 4.2 drivers. Therefore, JPA vendors should support both mechanisms (since the JDBC 4.2 mechanisms allow saving with timezones, which JDBC 4.1 does not).
  • It is an error if the @TemporalIncludeTimeZone or @TemporalTimeZoneColumn annotations are present on properties of any type other than Calendar, OffsetTime, OffsetDateTime, and ZonedDateTime.
  • A Calendar, OffsetTime, OffsetDateTime, or ZonedDateTime must be converted from its time zone/offset to the database server's time zone/offset on persistence if and only if neither @TemporalIncludeTimeZone nor @TemporalTimeZoneColumn are present on the property. If either of those are present, time zone/offset conversion is not necessary because the time zone/offset will be saved with the time (either using setObject or a second column). Upon retrieval from the database, neither the date/time value nor the time zone/offset value should ever be altered. It should be accepted as it comes back from the database, whether stored together in the same column or separately in two columns.
Comment by Nick Williams [ 12/Aug/13 ]

Another note:

  • In addition to the int, Integer, short, Short, long, Long, and Timestamp types currently supported for @javax.persistence.Version-annotated properties, properties of type Instant may also be @Version-annotated.
Comment by mister__m [ 20/Feb/14 ]

YearMonth and MonthDay columns can also be mapped to INTEGER columns.

Comment by reza_rahman [ 25/Mar/14 ]

I must say this is an excellent initial analysis. For folks interested, the official Java Tutorial now has a nice trail on the Java SE 8 Date/Time API: http://docs.oracle.com/javase/tutorial/datetime/index.html. Details on JDBC 4.2 here: http://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/jdbc_42.html.

Comment by braghest [ 13/Apr/14 ]

Don't do ISO-8601 formatted CHAR/VARCHAR-type fields violate 1st normal form?

Comment by tomdcc [ 02/Jun/14 ]

Some databases such as Postgresql support storing time intervals [1], so the Duration and Period types should be allowed to map to such types if the underlying database supports them.

[1] http://www.postgresql.org/docs/9.3/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT

I believe that interval is an ANSI SQL standard type

Comment by perceptron8 [ 14/Jan/15 ]

Properties of type java.time.MonthDay are treated as @Basic fields.
By default they automatically map to:

  • ...
  • DATE and DATETIME fields storing the lowest year number that the database vendor supports and zero-time if applicable; and,
  • ...

This year must be also a leap year. Sadly, Date.valueOf(MonthDay.of(1, 1).atYear(0)) becomes "0001-01-01", so it can't be 0.

Comment by mkarg [ 26/Mar/15 ]

While I indeed support this feature request due to its common purpose, there actually is no real need for it anymore, thanks to the acceptance of the adapter API proposal filed by me in https://java.net/jira/browse/JPA_SPEC-35: You can just write a simple adapter that does the type conversion at runtime. Or are you aiming on schema creation instead of just type conversion?

Comment by ymajoros [ 27/Mar/15 ]

Yeah, but I think it would be a good idea to mention out-of-the box support in the spec, that providers can implement this way if they want. Otherwise, we'll end up basically having to package boiler-plate code every time we use java.time.* classes for JPA support.

Comment by mkarg [ 27/Mar/15 ]

While that is absolutely correct, the technical answer is a bit more complex: What is the final predicate that makes a data type eligible for inclusion in the set of mandatory type mappings?

One could say, that predicate is "being essential" or "being of common use", but who defines what "essential" or "common use" is? See, for some applications, support for java.awt.Image and java.net.URL might be much more essential than support for LocalDate or ZonedDateTime. On the other hand, other applications might be full of LocalDate but never uses Instant. So where exactly to make the cut? This becomes particularly complex when looking at the sheer amount of types found in the JRE, and it is obvious there has to be a cut somewhere. Even JavaFX, which is bundled with the JRE, does not support Instant still in v8, so why should JPA? And looking at the current progress of Project Jigsaw, possibly the qualifying predicate might simply be answered by "all types in a particular jigsaw module"?

Anyways, it is not up to me to decide. I do support your request, and would love to see support for rather all Java Time API times, particularly for Instant and Duration, and your request has prominent supporters like for example Java Champion Arun Gupa as I learned recently. But I doubt the final answer will be as simple an satisfying as we would love to have it.

Maybe it would be better to simply set up another JSR, like "Common Data Type Conversions for the Java Platform", which provides much more mappings than just date and time, but also would not be bound to JPA but also could be used by JAXB, JAX-RS, and possibly more API that deal which the problem of transforming "<A> to <B>"? Having such a vehicle would really reduce boilerplate a lot.

Comment by braghest [ 28/Mar/15 ]

there actually is no real need for it anymore, thanks to the acceptance of the adapter API proposal

I'm not sure. Firstly currently the RI explodes with a ClassCastException when trying to write an attribute converter mapping a java.util.Calendar database value. Secondly the spec would have to say that when mapping a java.util.Calendar the time zone of the value returned from the database is the time zone of the value on the database instead of the time zone of the Java virtual machine (like java.sql.Date). JDBC only allows to access the time zone of a value using the Java 8 Date and Time API.
If you currently want to access the timezone of a database value you need to use vendor specific extensions.

Comment by Lukas Jungmann [ 14/Sep/15 ]

will try to address this in 2.2

Comment by neilstockton [ 02/Feb/16 ]

The description for Period is wrong in that it implies that this type stores seconds+nanos, whilst it actually is YEAR+MONTH+DAY ("A date-based amount of time in the ISO-8601 calendar system"). Consequently it is not possible to store it in DECIMAL, and likely not INTEGER also.

Comment by richardwalker [ 15/Dec/16 ]

Please consider including support for a "pure UTC" data flow at least in the following specific sense:

  • Java default time zone can be set to anything (to be specific, not UTC)
  • Some of the attributes of an entity class are specified as LocalDateTime, where the values are considered to be in UTC
  • Schema generation makes database columns of a "TIMESTAMP-like" type (actually, for MySQL I would override and use DATETIME in order to get a wider range of values)
  • Values are sent back/forth to the database "as is"
  • At no point do the values get converted to/from the default time zone (or any other time zone), so as to avoid the issue with confusion of values during daylight saving changeover

I don't see how to achieve this with JPA as is.

Until yesterday I have been using an AttributeConverter like this, based on code that can be found on several blogs:

@Converter(autoApply = true)
public class LocalDateTimeConverter implements
    AttributeConverter<LocalDateTime, Timestamp> {

    @Override
    public Timestamp convertToDatabaseColumn(
            final LocalDateTime attribute) {
        if (attribute == null) {
            return null;
        }
        return Timestamp.valueOf(attribute);
    }

    @Override
    public LocalDateTime convertToEntityAttribute(
            final Timestamp dbData) {
        if (dbData == null) {
            return null;
        }
        return dbData.toLocalDateTime();
    }
}

I now realise that although this seems to work, it is wrong, because both Timestamp.valueOf() and Timestamp.toLocalDateTime() interpret the value as though it were in the default time zone, so the code breaks during daylight saving changeover when there's an hour of time that doesn't "exist" in the default time zone.

For example, consider the test value 2016-10-02 02:02:01, which is a perfectly valid time when interpreted as UTC, but which does not exist in my local time zone (Australia/Sydney). If I (with default time zone Australia/Sydney) use the above converter to persist the LocalDateTime value LocalDateTime.of(2016, 10, 2, 2, 1, 0), the value is sent to the database, and stored, as '2016-10-02 03:01:00.0', and when it is read back into a LocalDateTime, its value is now one hour out! (I've done exactly this test to confirm.)

My converter is now like this:

@Converter(autoApply = true)
public class LocalDateTimeConverter implements
    AttributeConverter<LocalDateTime, Timestamp> {

    @Override
    public Timestamp convertToDatabaseColumn(
            final LocalDateTime attribute) {
        if (attribute == null) {
            return null;
        }
        return Timestamp.from(attribute.toInstant(ZoneOffset.UTC));
    }

    @Override
    public LocalDateTime convertToEntityAttribute(
            final Timestamp dbData) {
        if (dbData == null) {
            return null;
        }
        return LocalDateTime.ofInstant(dbData.toInstant(), ZoneOffset.UTC);
    }
}

but this doesn't work as is; it requires the recently-added Hibernate-specific configuration (explained at http://in.relation.to/2016/09/12/jdbc-time-zone-configuration-property/) to specify using UTC when sending Timestamp values through JDBC:

hibernate.jdbc.time_zone=UTC

So, although LocalDateTime values are "in theory" separate from concerns about time zones, it seems that when it comes to persisting them as Timestamp values, the values must be interpreted as being in some time zone.

So, please consider providing some way of specifying that LocalDateTime values are persisted in a "transparent" way (avoiding all internal time zone conversions along the way), or, if that is not possible, specifying the time zone in which LocalDateTime values are to be interpreted.

Comment by braghest [ 26/Jan/17 ]

richardwalker you're using UTC in the database and something else (eg. Australia/Sydney) in the JVM. I would strongly advise against when using LocalDateTime.
To illustrate the point imagine you have 2017-04-02 02:50:00+11:00 and 2017-04-02 02:10:00+10:00 two instants, 20 minutes apart. Now because you're using LocalDateTime as input and because your JVM time zone isn't UTC what you tell the database to store is 2017-04-02 02:50:00 and 2017-04-02 02:10:00. Note that now the dates are in a different order and 40 minutes apart. You have silent data truncation.
Normally I would recommend to use TIMESTAMP WITH TIME ZONE even if you're using UTC, unfortunately MySQL doesn't support that yet.

Since you're using Hibernate I would normally recommend you use a UserType instead of an AttributeConverter since it gives you direct access to the PreparedStatement and ResultSet. If the driver supports JSR-310 data types you can use them natively without converting. Unfortunately Connector / J currently converts through java.sql types which still leaves it vulnerable to the issues you observed.

Until this issue is fixed I would recommend you:

  • use OffsetDateTime or ZonedDateTime in your application, then first convert to UTC and then to LocalDateTime
  • use a Hibernate UserType and pass the java.time types to the driver
  • test with timestamps during both winter → summer time and summer → winter time transitions
  • consider running your JVM in UTC
Comment by richardwalker [ 27/Jan/17 ]

To illustrate the point imagine you have 2017-04-02 02:50:00+11:00 and 2017-04-02 02:10:00+10:00 two instants, 20 minutes apart.

But I wouldn't (and I don't).

As I wrote:

Some of the attributes of an entity class are specified as LocalDateTime, where the values are considered to be in UTC

So I would have – following the values in your example – two LocalDateTime values LocalDateTime.of(2017, 4, 1, 15, 50, 0) and LocalDateTime.of(2017, 4, 1, 16, 10, 0). And I would want those to be persisted in my database, in columns of type DATETIME, as the values '2017-04-01 15:50:00' and '2017-04-01 16:10:00'. And when they are read back in, they are converted back into the original LocalDateTime values.

And with the combination of:

  • the second version of the LocalDateTimeConverter class
  • the Hibernate-specific setting hibernate.jdbc.time_zone=UTC

this is the behaviour I get.

I think I do not actually need a "solution" to my problem: I now seem to have one that works. The point of my first message is that the particular combination of the five dot points at the top of the message seems not to be currently achievable with "pure" JPA (i.e., without Hibernate-specific settings).

You have mostly offered both non-alternatives (e.g., setting the JVM's timezone to UTC, which, at least for now, I can not do), and alternatives that also do not use "pure" JPA!

I do thank you for suggesting to have a look at ZonedDateTime and OffsetDateTime. From a modelling point of view, these two classes allow modelling the fact that the values in my program do belong to a particular time zone (i.e., UTC).

So, if you don't like my use of LocalDateTime, I now present the original problem, modified to use ZonedDateTime.

I want a solution that has all of these features:

  • Java default time zone can be set to anything (to be specific, not UTC)
  • Some of the attributes of an entity class are specified as ZonedDateTime, where the ZoneOffset of the values is UTC
  • Schema generation makes database columns of a "TIMESTAMP-like" type (actually, for MySQL I would override and use DATETIME in order to get a wider range of values)
  • Values are sent back/forth to the database as UTC values
  • At no point do the values get converted to/from the default time zone (or any other time zone), so as to avoid the issue with confusion of values during daylight saving changeover

And again: I don't see how to achieve this with JPA as is.

Here is the converter class using ZonedDateTime:

@Converter(autoApply = true)
public class ZonedDateTimeConverter implements
    AttributeConverter<ZonedDateTime, Timestamp> {

    @Override
    public Timestamp convertToDatabaseColumn(
            final ZonedDateTime attribute) {
        if (attribute == null) {
            return null;
        }
        return Timestamp.from(attribute.toInstant());
    }

    @Override
    public ZonedDateTime convertToEntityAttribute(
            final Timestamp dbData) {
        if (dbData == null) {
            return null;
        }
        return ZonedDateTime.ofInstant(dbData.toInstant(), ZoneOffset.UTC);
    }
}

And again, this doesn't work as is, for the same reason as before: the converted Timestamp values are persisted in the local time zone, not in UTC. The Hibernate-specific setting hibernate.jdbc.time_zone=UTC is still required to make it work. I conclude: the Hibernate-specific property hibernate.jdbc.time_zone=UTC does actually solve a problem; it is not "syntactic sugar" for something you can do another way in "pure" JPA.

So maybe it boils down to: please add a JPA setting that achieves what hibernate.jdbc.time_zone=UTC does. And maybe consider making the application of the setting scope-able (e.g., to individual fields).

Comment by braghest [ 27/Jan/17 ]

richardwalker You're correct, I missed that part

Some of the attributes of an entity class are specified as LocalDateTime, where the values are considered to be in UTC

and in this case your code works as long as everybody remembers that in your application for your entities LocalDateTime means UTC.

Once somebody writes

LocalDate.now()

instead of

LocalDate.now(ZoneOffset.UTC)

it breaks.

The last converter you posted fixes this.

Comment by richardwalker [ 07/Feb/17 ]

For anyone reading this who wants to use my code, note that for MySQL you'll need to add these parameters to the JDBC URL:

&serverTimezone=UTC&useLegacyDatetimeCode=false

otherwise you "fall at the last hurdle" (i.e., the JDBC driver ruins everything when it converts Timestamp values to strings).

Other databases may require something similar.





[JPA_SPEC-115] add @Repeatable(containerClass.class) to all existing annotations for which there exists a container annotation Created: 14/Sep/15  Updated: 10/Feb/17

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.2
Fix Version/s: 2.2

Type: Task Priority: Major
Reporter: Lukas Jungmann Assignee: Lukas Jungmann
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to JAVAEE_SPEC-36 Adapt to Java SE 8 Repeating Annotations Open

 Description   

ie. Convert (Converts), NamedQuery (NamedQueries) etc

see https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html for reference



 Comments   
Comment by neilstockton [ 08/Nov/16 ]

This is apparently already provided by DataNucleus in their "javax.persistence" jar. They don't seem to need Oracle to push JPA forward.
https://datanucleus.wordpress.com/2016/11/08/repeatable-annotations-for-jdo-and-jpa/

Comment by Lukas Jungmann [ 10/Feb/17 ]

has been done in http://git.eclipse.org/c/eclipselink/javax.persistence.git/commit/?id=f9db12ae58aab438ecbf09467f0c430d40eab4f1

should be eventually applied also to:

  • javax.persistence.SequenceGenerator
  • javax.persistence.TableGenerator




[JPA_SPEC-42] Allow null @Embedded Objects Created: 17/Jan/13  Updated: 05/Dec/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: reza_rahman Assignee: ldemichiel
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

At the moment, it is not possible to have null @Embedded objects in JPA (while Hibernate, etc allow it). This is quite a common scenario in most domain models that JPA should take into account. The following is an example:

<pre>
public class Employee {
...
@Embedded(optional=true) // This should be possible since the employee entity can be null in some
// stages of it's life-cycle
private Address address;
...
}
</pre>



 Comments   
Comment by neilstockton [ 05/Dec/16 ]

Just using "optional" doesn't define how a JPA provider can distinguish between a NULL embedded object and an embedded object with null fields.

The JDO spec provided a definition for this problem.

"null-indicator-column" defines which column used by the embedded object is for determining a null object, and "null-indicator-value" defines the value in that column that means we have a null object. So then the JPA provider can persist this null value in the null column on persist of a null embedded object, and ditto when retrieving.





[JPA_SPEC-137] API improvements - pass List to where Created: 26/Oct/16  Updated: 26/Oct/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: ymajoros Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Cloners
clones JPA_SPEC-44 API improvements Closed

 Description   

Quite happy to see jpa 2.1 is near...

I couldn't seem to subscribe to the mailing list, so here are some comments.

Some minor question/suggestion, maybe already discussed?

Why do we have this:

CriteriaQuery<T> where(Predicate... restrictions);

But not, additionnally, this:

CriteriaQuery<T> where(List<Predicate> restrictions);

While there is:

CriteriaQuery<T> groupBy(Expression<?>... grouping);
and
CriteriaQuery<T> groupBy(List<Expression<?>> grouping);

And List parameters for having, orderBy, ...



 Comments   
Comment by ymajoros [ 26/Oct/16 ]

Just cloned this issue, because:

  • JPA 2.1 is done but this would still improve the API
  • JPA 2.2 is in the air
  • As I understand it, Java 8 will be required in JPA 2.2, so it's now quite trivial to add a few default methods in EntityManager interface.

Why do we need this?

I typically have a bunch of optional search queries, which I transform into predicated:

if (namePrefix != null) {
   Predicate namePredicate = ...
   predicates.add(namePredicate);
}

// boiler-plate
Predicate[] predicateArray = predicates.toArray(new Predicate[0]);
query.where(predicateArray);

I'd like to just be able to to this:

 query.where(predicates);

Same for CriteriaBuilder::and (and ::or, etc.), which only accept arrays. I suggest adding a Collection<T> parameter to them.

This makes the Criteria API really dynamic (arrays aren't).





[JPA_SPEC-136] Unclear whether first writing or reading ddl sources files for schema generation Created: 20/Sep/16  Updated: 20/Sep/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: JesperTejlgaard Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It is unclear in section 9.4 of the JPA 2.1 spec whether data is written to e.g. the javax.persistence.schema-generation.scripts.drop-target before reading from javax.persistence.schema-generation.drop-script-source and executing changes or the other way round.



 Comments   
Comment by JesperTejlgaard [ 20/Sep/16 ]

Simple tests showed that Hibernate 5.2.2 is apparently reading and executing sources before writing to targets.





[JPA_SPEC-135] Unclear file handling for javax.persistence.schema-generation.scripts.drop-target and javax.persistence.schema-generation.scripts.create-target Created: 20/Sep/16  Updated: 22/Sep/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: JesperTejlgaard Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It seems unclear in the JPA 2.1 specification whether files specified in the javax.persistence.schema-generation.scripts.drop-target and javax.persistence.schema-generation.scripts.create-target properties are expected to overwrite an existing version of such a file or to append to the file.

It seems that Hibernate has chosen to append to existing files resulting in a growing file if not deleted by other processes.



 Comments   
Comment by neilstockton [ 22/Sep/16 ]

And DataNucleus JPA seems to overwrite the DDL when I use it which, for my usage, seems like a much better default behaviour.





[JPA_SPEC-133] Make TABLE-generated IDs available on PrePersist Created: 09/Aug/16  Updated: 22/Aug/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: jinahya Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: generator, id, lifecycle

 Description   

JSR-338/3.5.3 states that

> Generated primary key values are available in the PostPersist method.

It'll be much helpful if those ids whose strategy is GenerationType.TABLE are available on PrePersist.

exempli gratia

public class MyEntity {

    @PrePersist
    private void onPrePersist() {
        // generate a unique and unchangable value from *available* id.
        derived = String.format("%1$016x", id);
    }

    @GeneratedValue(..., strategy = GenerationType.TABLE)
    @Id
    private Long id;

    @Basic(optional = false)
    @Colum(..., nullable = false, updatable = false)
    @NotNull
    private String derived;
}

Note that the derived column is not null and not updatable.



 Comments   
Comment by neilstockton [ 22/Aug/16 ]

FWIW DataNucleus JPA already does set ids from all non-IDENTITY value generators (i.e TABLE, SEQUENCE, custom) prior to PrePersist, so hence the values are available in that method.





[JPA_SPEC-132] Change TableGenerator/initialValue's type to long Created: 05/Aug/16  Updated: 05/Aug/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: jinahya Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: TableGenerator
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

On some systems, initialValue need to be set with a large starting number bigger than Integer.MAX_VALUE.
Requesting considerations.






[JPA_SPEC-116] remove raw types from JPA API Created: 14/Sep/15  Updated: 14/Sep/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: 2.2
Fix Version/s: None

Type: Task Priority: Minor
Reporter: Lukas Jungmann Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

goal is for the API to compile cleanly but the key requirement is for API to remain backward compatible






[JPA_SPEC-109] Allow AttributeConverters to be CDI injectable Created: 11/May/15  Updated: 01/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2

Type: Improvement Priority: Minor
Reporter: Xavier Dury Assignee: Lukas Jungmann
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Since JPA 2.1, EntityListeners can be injected through CDI.

AttributeConverters could also be injectable in order to centralize conversion logic that can be shared between multiple components (like JSF Converters that will also be made injectable in 2.3).



 Comments   
Comment by Lukas Jungmann [ 13/Oct/15 ]

the request is to allow injection in the converter, right?

Comment by Xavier Dury [ 13/Oct/15 ]

indeed.

Comment by Lukas Jungmann [ 14/Oct/15 ]

thanks for confirming this. It wasn't clear from the initial description. Planned for the next release (the one currently in progress)

Comment by Lukas Jungmann [ 01/Nov/15 ]

implemented in RI, to try: https://www.eclipse.org/eclipselink/downloads/nightly.php if maven is prefered then see https://wiki.eclipse.org/EclipseLink/Maven for the repo setup





[JPA_SPEC-108] Path.get(PluralAttribute<X, C, E>) lower bound missing on X Created: 28/Apr/15  Updated: 28/Apr/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: mmariotti Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Path interface declares:

<E, C extends java.util.Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection);

it should be instead

<E, C extends java.util.Collection<E>> Expression<C> get(PluralAttribute<? super X, C, E> collection);

with lower bound on X.
The same apply on Path.get(MapAttribute<X, K, V>).






[JPA_SPEC-92] Sharing a single version field between multiple entities Created: 01/Oct/14  Updated: 01/Oct/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Xavier Dury Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I have been using Hibernate then JPA for almost 10 years and there is one feature that I miss and would like to be discussed by the EG.

Currently, in JPA, with a typical (bi-directional & mapped) Parent-Child relationship, the parent gets versioned when a child is added or removed from the parent collection.

I would like to know if it is possible to version the parent when a child is updated without artificially updating a dummy property on the parent (let's say lastModificationDate).

I'd like to do that to preserve an objects' graph coherence (invariants).

example:

I have the following entities:

[Order] 1 --- * [OrderLine (quantity)] * --- 1 [Product (price)] 

and have a rule (at the order level that can be implemented with javax.validation) that the total amount for an order (= sum quantity * price for each line) must not be greater than $5000.

If two users concurrently modify the same order by changing the quantity of 2 different lines, the last one committing won't see the changes made by the first one (even if each OrderLine has a @Version property) and won't be able to enforce the invariants on the parent order.

However, if the order itself is versioned at each commit (even if none of its direct property has changed but one of its children has been modified), the last one committing will get an OptimisticLockException (and the order won't be corrupted).

Therefore, I would like to be able to specify something like this:

@Entity
class Order {

    @Id
    Long id;
	
    @Version
    Integer version;
	
    @OneToMany(cascade = ..., mappedBy = "order")
    Set<OrderLine> lines;
}

@Entity
class OrderLine {

    @Id
    Long id;
	
    @ManyToOne
    @Version // if this orderLine changes, bump the version of the whole order
    Order order;
}

That way, I could have a single version field for a graph of objects. Speaking with Domain-Driven Design in mind, this would result in having a version field only on the aggregate root.

What do you think?






[JPA_SPEC-100] Allow an empty collection_valued_input_parameter in an "IN" expression Created: 21/Feb/15  Updated: 05/Dec/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Anthony Vanelverdinghe Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In section 4.6.9, In Expressions, it should be specified that an empty collection_valued_input_parameter must not result in an exception. More specifically:

the expression
o.country IN (:countries)
must be treated as false

and the expression
o.country NOT IN (:countries)
must be treated as true

This should be trivial for JPA implementations to implement, since they can simply replace the expression with an expression like "1 = 0" or "1 = 1".

Currently, JPA implementations throw an exception in this case, which makes it cumbersome to use collection valued input parameters.



 Comments   
Comment by jgigov [ 02/Dec/16 ]

Having no values between the parentheses causes an SQL syntax error in MySQL and PostgreSQL. I don't have other databases to test it with.
A way to simulate no results is to replace the parameter within parentheses with a subquery like this: select 1 where false. This workaround worked for both with integer fields, but PostgreSQL will never accept it if it can't resolve the types and find a conversion function. The fact that there is nothing to convert is irrelevant to it.

Comment by datanucleus1 [ 05/Dec/16 ]

DataNucleus JPA has always supported checking for empty input lists and generating the SQL as you show.
If your JPA provider doesn't then raise a bug on them (though the JPA spec should be explicit about what should happen in that situation as per your description)





[JPA_SPEC-82] Add an EntityManager#getReference() method that takes an ID and a version Created: 01/Jul/14  Updated: 01/Jul/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: ljnelson Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Please consider adding an EntityManager#getReference(Class, Object, Object) method to the JPA specification.

The method's purpose should be to return an entity provided that its identifier and version are equal to the supplied parameters.

It should be possible to pass null as the third parameter (version).

The javadoc could read something like the following:

/* 
 * Get an instance, whose state may be lazily fetched, provided that the
 * supplied class, identifier and version parameters collectively identify the
 * persistent representation of the entity in question.
 *
 * <p>If the requested instance does not exist in the database, an 
 * {@link EntityNotFoundException} is thrown when the instance state
 * is first accessed. (The persistence provider runtime is permitted to throw
 * the {@link EntityNotFoundException} when {@code getReference} is
 * called.)</p>
 * 
 * <p>The application should not expect that the instance state will be  
 * available upon detachment, unless it was accessed by the application while 
 * the {@link EntityManager} was open.</p>
 *
 * @param entityClass the {@link Class} of the entity being sought; must not
 * be {@code null}
 * 
 * @param primaryKey the identifier of the entity being sought; must not be
 * {@code null}
 *
 * @param version the version of the entity being sought; may be {@code
 * null} in which case this method will behave in exactly the same manner as
 * the {@link #getReference(Class, Object)} method
 *
 * @return the found (non-{@code null}) entity reference
 *
 * @exception IllegalArgumentException if {@code entityClass} does not 
 * denote an entity type or {@code primaryKey} is not a valid type for that
 * entity's primary key or is {@code null}
 *
 * @exception EntityNotFoundException if the entity state cannot be accessed
 */

The background for this issue can be accessed in the following email thread: https://java.net/projects/jpa-spec/lists/users/archive/2014-06/message/0






[JPA_SPEC-84] Add support for EL expressions in JPA-QL and native queries. Created: 18/Jul/14  Updated: 19/Jul/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: thomasd Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

This proposal suggests adding support using EL expressions in JPA query strings. With this one could define query string templates and dynamic parameter bindings based on EL (Expression Language).

  • Immediate evaluation (via $ {...}) could be used to statically alter the query string in cases where the user
    wants to statically generate a fixed part of a query. This could be used to add query fragments or adjust the name
    of tables or columns / fields.
    - Deferred evaluation (via #{...}

    ) could be used to dynamically compute a parameter value in cases where the user
    wants to avoid having to compute and set the parameter values explicitly.

Example 1

The JPA-QL query:

select o from BusinessObject o where o.owner.emailAddress like ?#{hasRole('ROLE_ADMIN') ? '%' : principal.emailAddress}

would translate to:

select o from BusinessObject o where o.owner.emailAddress like ?1

With ?1 bound to the result of the dynamically evaluated EL expression hasRole('ROLE_ADMIN') ? '%' : principal.emailAddress. The parameter ?1 would be dynamically registered.

Example 2

The JPA-QL query:

select o from BusinessObject o where o.owner.emailAddress = ?1 ${ currentTenant != null ? ' and o.tenant = ?#{' + currentTenant.id + '}' : ''}

would translate to either:

select o from BusinessObject o where o.owner.emailAddress = ?1

or:

select o from BusinessObject o where o.owner.emailAddress = ?1 and o.tenant = ?2

where ?2 is bound to the result of the dynamically evaluated expression "currentTenant.id".

It would be helpful to have some kind of SPI at the EntityManagerFactory that allows libraries or users to customize the EL expression context somehow, e.g. by allowing to expose functions, properties, variables and the like.

javax.el.Expression as JPA Query parameter values

As an extension one could also allow to bind parameter values of type javax.el.Expression to every exposed parameter of a JPA query. The value to be bound could then derived at query time by evaluating the given expression. We implemented that feature in the latest version of the Spring Data JPA Repository abstraction.



 Comments   
Comment by thomasd [ 18/Jul/14 ]

Sorry for the bad formatting...
I wanted to fix it, but I cannot edit the issue anymore

It should look like the following gist:
https://gist.github.com/thomasdarimont/96ca7a913c8b0ffcf970

Cheers,
Thomas





[JPA_SPEC-81] @Version Support for Temporal Types Created: 22/May/14  Updated: 22/May/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: shelleyb Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The JPA 2.1 specification currently indicates that Timestamp is the only supported temporal type for @Version properties:

The following types are supported for version properties: int, Integer, short, Short, long, Long, Timestamp.

I'd propose that additional temporal types are supported as well:

java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp



 Comments   
Comment by shelleyb [ 22/May/14 ]

For reference, Hibernate already seems to support this, and as such, we had initially overlooked this jpa limitation and are already using @Version java.util.Calendar in our entities, and I have observed this usage elsewhere as well:

https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch05.html#mapping-declaration-timestamp





[JPA_SPEC-68] update and/or validate javax.persistence.schema-generation.database.action Created: 12/Nov/13  Updated: 12/Nov/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: steveschols Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: schema-generation, update, validate

 Description   

I think that an "update" and a "validate" schema-generation.database.action might come in handy, especially for production environments where Java EE 7 will be running in the comming future.

Of course you don't want your database to be accidentally being removed if you still have the "create-drop" enabled, and a new action won't solve that.
But without the "update" action you still have to resort to solutions like Google Flyway or DbMaintain to update an existing database schema.

Are there plans to incorporate a new action like "update" or "validate", the way Hibernate supports it?
Or are they left out by design?






[JPA_SPEC-65] Need another property to make lazy loading of attributes easy with entity graphs Created: 31/Aug/13  Updated: 31/Aug/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: mkeith Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There are currently two properties to use with entity graphs:

javax.persistence.fetchgraph -

This property accepts an entity graph to act as a complete override of all the attributes for the type. Attributes are dictated to be eager if included or lazy if excluded from the graph, regardless of how they are mapped.

javax.persistence.loadgraph -

This property offers a selective eager approach. One can simply add the attributes that one wants to be eagerly loaded and the rest are left as they are statically mapped.

The missing property would be something to allow more convenient selective lazy overriding without having to declare the entire attribute set for the type (as required by fetchgraph). So something like:

javax.persistence.lazygraph -

This property would offer a selective lazy approach. One would be able to add the attributes that one wants to be lazily loaded to the graph, with the rest being left as they are statically mapped.






[JPA_SPEC-64] EntityGraph API has unspecified List/Map getters Created: 27/Aug/13  Updated: 27/Aug/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: mkeith Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The List/Map getter methods (e.g. getAttributeNodes()) on EntityGraph, AttributeNode, and Subgraph do not specify whether the List/Map returned is a mutable one or a copy. They should be specified as returning the exact collections so the collections can be mutated. If it is a copy then the ability to mutate an existing named entity graph using createEntityGraph(String) is quite limited. There would be no way to remove an attribute node or a subgraph, or for that matter even add a subgraph for an existing attribute node.

The alternative to returning the actual collections is to add methods to the API to enable the additional mutating operations.






[JPA_SPEC-59] Clarify namespaces of type aliases and named parameters Created: 11/Jun/13  Updated: 11/Jun/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Matthew Adams Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JPA 2.1


Tags: jpa, jpql, parameter

 Description   

JPA 2.1 Section 3.10.12, "Named Parameters", does not explicitly require that the namespaces of type aliases and named parameters be distinct. Some implementations fail & some succeed on JPQL of the following form:
SELECT x FROM Thing x WHERE x.foobar = :x

The specification should be explicit as to whether type aliases and named parameters share the same namespace.






[JPA_SPEC-53] Schema generation with existing EMF Created: 26/Mar/13  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Christian Bauer Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I've been running into a conceptual issue with schema generation in JPA 2.1 and how unit tests are typically organized.

Let's say you want a clean database for every unit test method. I prefer to create the schema in the database before every test method, and then drop it after the test method completes.

I have a single EntityManagerFactory for the whole test class, it can be shared by every test method. This is possible with the Hibernate API, the schema generator uses an existing EMF configuration to produce the create/drop scripts.

With the static Persistence.generateSchema() in 2.1 this approach doesn't work. Calling generateSchema() internally builds a new EMF every time.

One of the problems is that you get new automatically generated foreign key names every time you call generateSchema(). The "drop" action therefore always fails, unless you define all foreign key names in your metadata. There could be other automatically generated artifact names, so the "drop" action in general, if called from a static context, is not useful during development.

The current solution then is to specify "drop-and-create" and to build and close an EMF for every unit test method. This means starting and stopping the persistence provider for every test method, slowing down test runs significantly.

A better solution would be an additional Persistence.generateSchema(EMF, properties) method that accepts an existing EMF and some "override" properties.



 Comments   
Comment by Christian Bauer [ 04/Apr/13 ]

Additionally, consider adding the database action "create-drop". This would issue CREATE statements when the EMF is build, and DROP statements when the EMF is closed. Granted, this is a useless setting with static Persistence.generateSchema() but it would, in addition to the above proposed changes, give you full flexibility for schema generation. Use case is for example a @BeforeMethod in a test harness that builds an EMF and an @AfterMethod that closes the EMF.





[JPA_SPEC-52] createNativeQuery(String, Class) Created: 20/Mar/13  Updated: 29/Nov/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: agoerler Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi,

I've got a minor suggestion:

EntityManager.createNativeQuery(String, Class)

could return a TypedQuery as the result class is specified:

TypedQuery<T> createNativeQuery(java.lang.String sqlString,
java.lang.Class<T> resultClass)

-Adrian



 Comments   
Comment by edvin [ 05/May/14 ]

Is there a more complex underlying reason for this not being fixed? At first glance it seems trivial.

Comment by hirdil [ 28/Nov/16 ]

It would be nice to have this feature.

Comment by neilstockton [ 29/Nov/16 ]

You mean, apart from the fact that there already is a method
createNativeQuery(String sqlString, Class resultClass)

returning Query. So for backwards compatibility you can't just change the signature. Unless backwards compatibility is thrown away of course ...





[JPA_SPEC-30] Case sensitivity in JPQL queries Created: 24/May/12  Updated: 23/Nov/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: arjan tijms Assignee: ldemichiel
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: RFE

 Description   

In JPA 2.0, JPQL is case insensitive. This means that contrary to Java code, an identifier can not be same name as an entity with the first letter in lower case.

For instance in the following query an underscore has to be added to make the name legal:

SELECT
    _user
FROM
    User _user

Other typical workarounds for this are abbreviating the identifier to e.g. "u", "usr" etc. Such names are rarely a best practice and actually against common advice for good naming given by books like Clean Code, etc.

I would like to request support for case sensitivity in some way, or alternatively to lift the requirement that identifiers may not have the same name as Entity classes. This last approach is taken by some persistence providers, e.g. Hibernate, which silently accepts identifiers having the same name as Entities.

One possible solution would be to use a setting, either per query or globally for the entire persistence unit. E.g.

<named-query name="User.getAll" caseSensitive="true">
    <query>
        SELECT
            user
        FROM
            User user
    </query>
</named-query>


 Comments   
Comment by c.beikov [ 24/Apr/13 ]

Would it break backwards compatibility? I don't think so.
IMO this is an important addition when there is no reason for not including it. Many developers just use "propritary features" of their persistence providers and don't even know for sure that it isn't standard. I used hibernate ever since and I didn't know JPQL is case insensitive. So if I really want to deploy my applications to servers that do not have hibernate on them and the JPA implementation of the target system is not case sensitive, I would have to rewrite 300+ queries to get it working

Please consider the addition or give reasons for not doing it!

Comment by pbenedict [ 23/Nov/15 ]

Interesting addition. Adding caseSensitive to both the descriptor and @NamedQuery seems sensible, but most queries that I've seen (SQL and JPQL) have standardized on the one letter alias convention. I probably did hit this problem once but it's just too easy to use another alias.





[JPA_SPEC-23] add a prefixing mechanism for @Embedded Created: 10/May/12  Updated: 15/Apr/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: Mark Struberg Assignee: ldemichiel
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: RFE

 Description   

Currently working with @Embedded is not really user friendly. If you have multiple Embedded fields in an Entity, then you need to excessively use @AttributeOverrides to use them. This is not only a real nightmare to write down, but also an absolute pain when it comes to refactoring or if you just add or remove a column.

It gets even worse if you have a nested @Embedded structure!

The solution could be to allow specifying a 'prefix' as JDO knows it for years.

Let's first look at the Embeddable

@Embeddable 
public class Address {
  private String name1;
  private String name2;
  private String street1;
  private String street2;
  private String zip;
  private String tel;
  // ... + getters and setters
}

(please let's not argue about whether this should better be stored 1:n but just take it as sample for now)

Then we look at a possible solution with the prefix:

@Entity
public class Customer {
 ...

  @Embedded(prefix="S_")
  private Address serviceAddress;

  @Embedded(prefix="B_")
  private Address billingAddress;

  @Embedded(prefix="P_")
  private Address physicalAddress;
}

You all know what pain it is to do the same in JPA right now ...



 Comments   
Comment by mkeith [ 15/May/12 ]

Yes, this is a possiblity, although I'm not fond of mixing a logical annotation with a physical column prefix, but the idea is fine, and it wouldn't necessarily need to be part of the embedded annotation.
Prefixes would presumably not be applied to explicit overrides, so it would be more like a default prefix.
I suppose the prefix would apply to the nested embeddables as well?

Comment by Mark Struberg [ 20/May/12 ]

I see what you mean with the separation of the java side and the db side. Maybe you could see this as 'logical' prefix which by default gets mapped 1:1 to a column prefixing logic like with the column names?

As for nested embedded fields imo the prefixes should also get nested.

In our application we use a

@Embeddable
public LocalizedText {
  private String en;
  private String de;
  private String fr;
}

Now imagine that the Address class above has two fields private @Embedded LocalizedText comment with a prefix='C_' and internalInfo with prefix='I_'.

That would end up with the columns
S_C_name1, S_C_name2,.. S_I_name1, S_I_name2,... B_C_name1, B_C_name2,...

Comment by Paul Benedict [ 11/Apr/14 ]

I agree that mixing the logical and physical is not ideal (see comment #1). Besides, if someone wants prefixes, someone else is likely to want suffixes too, or some other complex customization. I propose that the developer should specify a class that can preprocess the column name. The benefit to this approach would be the spec wouldn't dictate/shoehorn the customizations allowed.

For example, called once per attribute of an emeddable/entity:

public interface PhysicalCustomizer {
  String customizeColumn(ManagedType<?> mt, Attribute<?,?> attr, String originalColumnName)
}

Sample usage:

@Embeddable
@Customizer(MyPhysicalCustomizer.class)
Comment by c.beikov [ 15/Apr/14 ]

I think this is related to JPA_SPEC-12 if mutation of the meta- and physical model in case of preCreated callback is allowed.





[JPA_SPEC-20] add FetchType.LAZY/EAGER to @Lob fields and @Embeddable Created: 10/May/12  Updated: 05/Apr/13

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Mark Struberg Assignee: ldemichiel
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Afaik there is currently no way to specify a @Lob field as being lazy loaded.

BLOBS and LOBS often need a big amount of memory and are expensive to fetch from the database.

What about adding something like:

public class MyEntity {

  @Lob(FetchType.LAZY)
  private String someHistoryData;

}

Currently one always needs to create explicit list objects which get filled with 'new' in JPQL to not trash the database.

The same goes for @Embeddable. Though not needed that desperately it could be useful as well. (The whole Embedded would get lazily fetched when a single attribute of it is read).



 Comments   
Comment by Mark Struberg [ 14/May/12 ]

small note: it's for sure better to define the FetchType in each @Embedded and not in @Embeddable.

Comment by mkeith [ 15/May/12 ]

You can actually combine @Lob with @Basic, allowing you to specify a fetch type for any Lob attribute. I think this will give you what you want.

As far as Embedded objects go, any one of the embedded attributes can be individually specified to be lazy loaded but there is not currently a standard way to say that the embedded object should be lazy loaded as an object. My personal opinion is that if you get to that point then you are probably bordering on considering the embeddable as an independent privately owned entity and should make a relationship out of it instead of an embeddable, but that may just be me. We could get to the stage of adding a fetchType element on @Embedded, or we could handle this case through entity fetch groups.

Comment by ldemichiel [ 15/May/12 ]

I think it is reasonable to add FetchType to @Embedded. When we first introduced embeddables they were more limited in terms of what attributes they could have.

Comment by Mark Struberg [ 20/May/12 ]

Mike, Linda, thanks for pointing me to @Basic. I was actually not aware that I can use both @Basic and @Column on the same field - my fault. I always thought that @Column was a successor of @Basic, mostly because they have conflicting properties. E.g. having a

@Basic(optional=false)
@Column(nullable=true)
private String xxx;

lets me without a clue what should happen. But that is certainly another (minor) problem.

As for FetchType for Embedded fields: this is certainly not as big as an issue for the (now solved) @Lob question. Downgrade to minor? txs!

Comment by ldemichiel [ 30/Oct/12 ]

Downgraded priority to reflect comments





[JPA_SPEC-19] Upload official/standard JPA 2.0 API jar to Maven Central Created: 05/Apr/12  Updated: 05/Oct/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Matthew Adams Assignee: ldemichiel
Resolution: Unresolved Votes: 16
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: bundle, maven, mavenization, osgi, repositories, repository

 Description   

There is no official or standard JPA API jar available from the expert group in either Maven Central or the java.net Maven repo that both JPA users & implementors can utilize. Users are left to search for implementations' groupId, artifactId, & version values, which is inconvenient.

Please upload a binary jar (including class files and relevant resource files), a source jar, and a javadoc jar, under the groupId "javax.persistence", artifact id "jpa-api" and version "2.0". A minimal target Maven repository would be Maven Central, but others like java.net might be nice, too.

Bonus points for including OSGi bundle metadata (pretty easy if using Apache Felix's Maven Bundle Plugin, org.apache.felix:maven-bundle-plugin:2.3.7)!



 Comments   
Comment by Matthew Adams [ 13/Jun/13 ]

http://search.maven.org/#artifactdetails%7Cjavax%7Cjavaee-api%7C6.0%7Cjar

Is this intended to be the release? If so, it might do for some, but a standalone JPA API artifact would be ideal.

Comment by marcelstoer [ 05/Oct/15 ]

The same was requested for JPA 2.1 in JPA_SPEC-60. If the maintainers have no intention of fixing this they should at least close it with 'won't fix' - and ideally give an explanation.





[JPA_SPEC-77] EntityManager(Factory) should implement AutoCloseable Created: 13/Apr/14  Updated: 02/Dec/16

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: braghest Assignee: Unassigned
Resolution: Unresolved Votes: 8
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: autocloseable, java_7

 Description   

EntityManager and EntityManagerFactory have #close() methods but do not implement AutoCloseable. Implementing AutoCloseable would allow them to be used in Java 7 try-with-resource statement.



 Comments   
Comment by flutter [ 21/May/15 ]

This would mean to drop Java 6 support, right?

Comment by braghest [ 22/May/15 ]

That would mean dropping Java 7 support but then again Java EE 7 requires Java SE 7.

Comment by neilstockton [ 28/May/15 ]

It would mean dropping Java 1.6, yes. But then Java 1.6 and Java 1.7 are BOTH end of life now.
By the time the next version of JPA happens (who knows when that is), Java 1.8+ should be the baseline, hence no reason why this issue can't be included.
+1

Comment by jemiller1 [ 31/Aug/16 ]

Come on guys. It's 2016 and Java 8 has been out for over a year. Is this ever going to get implemented? It looks really obvious to me that this needs to happen. I don't know what to say about the whole Java standards process other than it's extremely slow. Coming from a .NET environment. It is a huge step backwards working with Java. I'm amazed that things as simple as this don't just work. And has already been pointed out Java 6 and 7 are already EOL.

Comment by s.grinovero [ 02/Dec/16 ]

For the record, we had this in Hibernate since a while, and initially implemented java.io.Closeable which just requires java 1.5. java.io.Closeable extends AutoCloseable since Java 7, so people on Java >=7 could use the try-with-resources pattern already.





[JPA_SPEC-101] Typo in the specification Created: 21/Feb/15  Updated: 21/Feb/15

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: Anthony Vanelverdinghe Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In section 4.12 of the specification (JSR 338 JPA 2.1 Final Release for Evaluation), "wrappered" should be "wrapped".






[JPA_SPEC-95] javadoc compilation prints out warnings on JDK8 Created: 12/Oct/14  Updated: 12/Oct/14

Status: Open
Project: jpa-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: Lukas Jungmann Assignee: ldemichiel
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Javadoc generation currently reports 441 warnings on JDK 8, it would be nice to get this to 0 warnings

 
 [javadoc] /Users/lukas/development/eclipselink/javax.persistence/src/javax/persistence/criteria/Subquery.java:178: warning: no @param for <V>
  [javadoc]     <X, K, V> MapJoin<X, K, V> correlate(MapJoin<X, K, V> parentMap);
  [javadoc]                                ^
  [javadoc] 441 warnings





Generated at Mon Feb 27 16:20:09 UTC 2017 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.