Bug 267701 - Need clear access to sequencing functionalities for unmanaged use case
Summary: Need clear access to sequencing functionalities for unmanaged use case
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 enhancement with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard: submitted_patch
Keywords:
Depends on:
Blocks:
 
Reported: 2009-03-09 14:32 EDT by Sebastien Tardif CLA
Modified: 2022-06-09 10:24 EDT (History)
3 users (show)

See Also:


Attachments
Fixes providing support to get sequence increment by sequenceName (6.56 KB, patch)
2009-04-29 15:15 EDT, Sebastien Tardif CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastien Tardif CLA 2009-03-09 14:32:45 EDT
95% of our application dealing with sequencing is handled transparently by EclipseLink when it assign id using sequence for the primary keys of managed objects.

The other 5% of our application is also using Oracle sequence and would like to use sequence pool provided by EcliseLink. 

The use cases are:
- generate badge id, it's not the primary key of Badge class
- generate unique number, that will be small and concatenated with some token. Need to be small so cannot be UUID/GUID.
- generate small unique identifier for identifing each HTTP request. Need to be unique between application servers in the cluster, and unique over very long time period.

Right now, we have a problem to access clientSessionSequencing.sequencingServer because it's not accessible so we end-up to create the class below. Please provide functionality and publish the usage.

package oracle.toplink.internal.sequencing;

import com.saic.ct.sys.persistence.common.CTSessionBroker;
import oracle.toplink.publicinterface.DatabaseSession;
import oracle.toplink.publicinterface.Session;
import oracle.toplink.sequencing.Sequence;

public class CTSequencingManager extends SequencingManager {

	private CTSequencingManager(DatabaseSession arg0) {
		super(arg0);
	}


	public static long getSequenceFor(CTSessionBroker broker, String sessionName, String sequenceName) {
		Session session = broker.getSessionForName(sessionName);
		ClientSessionSequencing clientSessionSequencing = (ClientSessionSequencing)session.getSequencing();
		SequencingManager sequencingManager = (SequencingManager)clientSessionSequencing.sequencingServer;
		Sequence sequence = sequencingManager.getSequence(sequenceName.toUpperCase());
		State state = sequencingManager.getState(sequence.shouldUsePreallocation(), sequence.shouldUseTransaction());
		
		return ((Number)state.getNextValue(sequence, session)).longValue();
		
	}
Comment 1 Sebastien Tardif CLA 2009-04-29 15:15:28 EDT
Created attachment 133821 [details]
Fixes providing support to get sequence increment by sequenceName

All the use cases implemented except that RemoteSession in combinaison with SessionBroker is not supported if SessionBroker has more than one child, which is normally the case. However, it's unlikely any customer use both at the same time.
Comment 2 Sebastien Tardif CLA 2009-04-29 15:27:16 EDT
With this enhancement, sequence can be used when not assigned to a specific class. Because you can get an increment (one item of the batch), by asking for it using the sequence name. 

Code example:

ClientSession clientSession = (ClientSession)session;
Sequencing clientSessionSequencing = clientSession.getSequencing();
long id = ((Number) clientSessionSequencing.getNextValue( clientSession, sequenceName)).longValue();

The API support SessionBroker, but you must pass the session child to getNextValue method.

Before the fix you need to use reflexion on or derive from a class using same package to get access.
Comment 3 Andrei Ilitchev CLA 2009-04-30 11:12:19 EDT
descriptor.setSequenceNumberName method assigns sequence name to descriptor that uses it (several descriptors could use the same sequence).

Eclipselink only uses sequences that are used by (at least one) descriptor - all other sequences are ignored. If not a single descriptor uses sequencing then SequencingManager no initialized at all.

descriptor.setSequenceNumberField should be called to designate the field to which sequnce value should be assigned (it's typically a pk, but not necessarily so).

To get a sequence value corresponding to a class directly, call
abstractSession.getNextSequenceNumberValue(myClass);

If you need a sequence that's not used by any other classes you define a dummy class that uses the sequence and add it to the project.

In the project there's (maximum) one sequence corresponding to each class, but possibly several sequence corresponding to the same sequence name (in SessionBroker several member-sessions may use the same sequence names).
So to find a sequence either a pair (session - non broker, sequenceName) or a class should be used: Eclipselink uses the latter approach.
Comment 4 Sebastien Tardif CLA 2009-04-30 11:16:53 EDT
I understand existing functionality. This is an enhancement. Our application is using the enhancement provided by the patch and it's working fine and better than workarounds you have listed.

We currently just need few lines of code to add a bunch of Oracle sequences and use EclipseLink to manage the pool. Starting to create fake classes will add complexity and look weird.
Comment 5 Andrei Ilitchev CLA 2009-04-30 11:40:47 EDT
You application will work exactly the same (neither better nor worse) with these workarounds or with your changes.

Your changes have holes: if the sequence is not there your code will throw NPE, in case the sequence is there but haven't been initialized (because it's not used by any descriptor) the NPE will be thrown on attempt to use this sequence (BTW, if it works for you then there is a descriptor that uses this sequence - so you can access the sequence using the current code, by the class).
Comment 6 Sebastien Tardif CLA 2009-04-30 11:51:16 EDT
In our application no descriptor is using the sequence we specify via the new method clientSessionSequencing.getNextValue( clientSession, sequenceName))

Initialization code is like this:

DefaultSequence newSeq = new DefaultSequence(sequenceName, iSize);
newSeq.onConnect(session.getDatasourcePlatform());
login.addSequence(newSeq);

Please work with me to improve the enhancement, so EclipseLink.
Comment 7 Doug Clarke CLA 2009-05-01 11:33:11 EDT
Would the new JPA2 unwrap methods simplify access:

SequenceControl sq = entityManager.unwrap(SequenceControl.class);

Or similar unwrap capabilities to simplify access to our sequencing interfaces?
Comment 8 Andrei Ilitchev CLA 2009-05-01 11:55:40 EDT
It's not about access to existing functionality, but rather request for a new one. Currently only sequences used by descriptors are initialized (not initialized sequences can't be used). Explicitly connecting individual sequence after login is a hack that works only in case there's another sequence of this type has been initialized (say, if we adding NativeSequence after login, it will work only in case there's at least one NativeSequence that has been initialized during login). Not to mention that this wouldn't work at all if the project doesn't use sequences (if there are no descriptors using sequences). It is definitely feasible to rework sequencing to initialize all sequences - not only the ones used by descriptors. However initializing of unused sequences may cause unnecessary usage of resources (such as allocating connections for sequencing connection pool only because one of unused sequences is a TableSequencing and useSequencingConnectionPools was set to true). Also accessing sequences by name may cause NPE and/or usage of not initialized sequences, which should throw some meaningful exceptions.

What I am trying to say is that this is certainly do-able, but is not trivial and would envolve a bit more then a simple addition of a couple of apis.
Comment 9 Eclipse Webmaster CLA 2022-06-09 10:24:32 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink