Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 347539 - HistoryPolicy Problem with PK GenerationType.IDENTITY on PostgreSQL
Summary: HistoryPolicy Problem with PK GenerationType.IDENTITY on PostgreSQL
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P2 normal with 10 votes (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard: postgresql
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-28 06:25 EDT by Ecmel Ercan CLA
Modified: 2022-06-09 10:24 EDT (History)
7 users (show)

See Also:


Attachments
A better correction of this bug (2.16 KB, text/x-java)
2015-03-09 10:15 EDT, Nicolas Marcotte CLA
nicolas.marcotte: review?
Details

Note You need to log in before you can comment on or make changes to this bug.
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