Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 347539

Summary: HistoryPolicy Problem with PK GenerationType.IDENTITY on PostgreSQL
Product: z_Archived Reporter: Ecmel Ercan <ecmel.ercan>
Component: EclipselinkAssignee: Nobody - feel free to take it <nobody>
Status: NEW --- QA Contact:
Severity: normal    
Priority: P2 CC: acc-clps, nicholas, nicolas.marcotte, nrutherford, renso, sam.ratcliff, tom.ware
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard: postgresql
Attachments:
Description Flags
A better correction of this bug nicolas.marcotte: review?

Description Ecmel Ercan CLA 2011-05-28 06:25:04 EDT
Build Identifier: 2.2.0.v20110202-r8913

If an entity has an auto generated id column, HistoryPolicy does not work with PostgreSQL.

Call: select lastval()
Query: ValueReadQuery(name="SEQ_GEN_IDENTITY" sql="select lastval()")

Caused by: org.postgresql.util.PSQLException

complaining that lastval is not yet defined.



Reproducible: Always
Comment 1 Tom Ware CLA 2011-05-31 10:11:45 EDT
Please post information about how you entity is defined and mapped.  (java, annotations, orm.xml, deployment xml)
Comment 2 Ecmel Ercan CLA 2011-06-03 07:26:04 EDT
@MappedSuperclass
@Customizer(EntityCustomizer.class)
public abstract class Persistent implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    private Integer version;

    protected Persistent() {
        super();
    }

    public Long getId() {
        return id;
    }

    public Integer getVersion() {
        return version;
    }
}

@Entity
public class Account extends Persistent {

    private static final long serialVersionUID = 1L;

    ...
}


In EntityCustomizer I set the HistoryPolicy. This works with SEQUENCE but not with IDENTITY.

Tested only on PostgreSQL.
Comment 3 Tom Ware CLA 2011-06-09 10:05:44 EDT
Setting target and priority.  See the following page for the meanings of these fields:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines

Community: Please vote for this bug if it is important to you.  Votes are one of the main criteria we use to determine which bugs to fix next.
Comment 4 Sam Ratcliff CLA 2011-09-15 11:44:29 EDT
This also is a problem with MS SQL Server
Comment 5 Nick Padilla CLA 2012-07-16 13:30:32 EDT
This is also a problem with MySQL but using SEQUENCE or TABLE strategies do not work.
Comment 6 Nicolas Marcotte CLA 2015-03-06 16:39:53 EST
here is a crude hack to fix this problem:

  HistoryPolicy historyPolicy = new HistoryPolicy(){      
            @Override
            public void logicalInsert(ObjectLevelModifyQuery writeQuery, boolean isUpdate) {
                Sequence oldValue = writeQuery.getDescriptor().getSequence();
                writeQuery.getDescriptor().setSequence(new Sequence(){

                    @Override
                    public boolean shouldAcquireValueAfterInsert() {
                        return false;
                    }

                    @Override
                    public boolean shouldUseTransaction() {
                       return false;
                    }

                    @Override
                    public Object getGeneratedValue(Accessor accessor, AbstractSession writeSession, String seqName) {
                         return new Object();
                    }

                    @Override
                    public Vector getGeneratedVector(Accessor accessor, AbstractSession writeSession, String seqName, int size) {
                        return new Vector();
                    }

                    @Override
                    public void onConnect() {
                       
                    }

                    @Override
                    public void onDisconnect() {
                        
                    }
                
                });
                
                super.logicalInsert(writeQuery, isUpdate);
                writeQuery.getDescriptor().setSequence(oldValue);
            }  
            
        };
Comment 7 Nicolas Marcotte CLA 2015-03-09 10:15:27 EDT
Created attachment 251408 [details]
A better correction of this bug

The quick and dirty hack I posted friday was not thread safe. It can lead to data corruption under load. Here is a cleaner, thread safe, fix.

The simplest way I found to fix this bug was, to clone the descriptor in the initialise method and to replace the sequance, with a DummySequance that does nothing.
Comment 8 Eclipse Webmaster CLA 2022-06-09 10:24:15 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink