package org.jeeventstore.persistence.jpa;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;

/**
 * JPA EventStore Entry.
 * @author alex
 */
@Entity
@Table(name = "event_store", uniqueConstraints = {
    @UniqueConstraint(columnNames = {"bucket_id", "stream_id", "stream_version"}),
    @UniqueConstraint(columnNames = {"change_set_id"})
})
public class EventStoreEntry implements Serializable {

    /**
     * ID of the entry.  Can be used to enumerate ALL Events.
     */
    @SequenceGenerator(name="event_store_id_seq", sequenceName="event_store_id_seq", allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="event_store_id_seq")
    @Column(name = "id", updatable = false)
    @Id
    private Long id;

    @Column(name = "bucket_id")
    @NotNull
    private String bucketId;

    @Column(name = "stream_id")
    @NotNull
    private String streamId;

    @Column(name = "stream_version")
    private long streamVersion;

    @Column(name="persisted_at")
    private long persistedAt;

    @Column(name = "change_set_id")
    @NotNull
    private String changeSetId;

    // cannot use @Lob due bug in Hibernate/Postgres combination, which both
    // sides refuse to fix, see
    // https://groups.google.com/forum/#!topic/pgsql.interfaces.jdbc/g4XXAL-a5tE
    // http://in.relation.to/15492.lace
    // https://hibernate.atlassian.net/browse/HHH-6127
    // we therefore fix the length at 32,672 , which is the maximum VARCHAR
    // size in Apache Derby.  In production, use an existing table in your DB
    // with the correct type set
    @Column(name = "body", length = 32672)
    private String body;

    public EventStoreEntry(
            String bucketId,
            String streamId,
            long streamVersion,
            long persistedAt,
            String changeSetId,
            String body) {

        //Validate.notEmpty(bucketId, "bucketId must not be empty");
        //Validate.notEmpty(streamId, "streamId must not be empty");
        //Validate.notEmpty(changeSetId, "changeSetId must not be empty");
        //Validate.notEmpty(body, "body must not be empty");

        this.bucketId = bucketId;
        this.streamId = streamId;
        this.streamVersion = streamVersion;
        this.persistedAt = persistedAt;
        this.changeSetId = changeSetId;
        this.body = body;
    }

    public Long id() {
        return id;
    }

    public String bucketId() {
        return bucketId;
    }

    public String streamId() {
        return streamId;
    }

    public long streamVersion() {
        return streamVersion;
    }

    public long persistedAt() {
        return persistedAt;
    }

    public String changeSetId() {
        return changeSetId;
    }

    public String body() {
        return body;
    }

    /**
     * Required for JPA, do not use
     * @deprecated 
     */
    @Deprecated
    protected EventStoreEntry() { }
    
}
@@ -1426,17 +1426,27 @@
 ;%0A%0A    /
-/
+*%0A     * We
  cannot 
@@ -1457,73 +1457,165 @@
 @Lob
- due bug in Hibernate/Postgres combination, which both%0A    // sid
+, because it will cause Hibernate to map the field%0A     * in ascii-only mode when used with PostreSQL, which leads to broken%0A     * UTF8 Strings.  Both parti
 es r
@@ -1626,16 +1626,26 @@
 e to fix
+ this isse
 , see%0A  
@@ -1642,26 +1642,26 @@
 se, see%0A    
-//
+ *
  https://gro
@@ -1723,26 +1723,26 @@
 AL-a5tE%0A    
-//
+ *
  http://in.r
@@ -1767,18 +1767,18 @@
 ace%0A    
-//
+ *
  https:/
@@ -1822,20 +1822,27 @@
 127%0A    
-// w
+ *%0A     * W
 e theref
@@ -1905,18 +1905,18 @@
 HAR%0A    
+ 
-//
+*
  size in
@@ -1932,91 +1932,219 @@
 erby
-.  In production, use an existing table in your DB%0A    // with the correct type set
+, the database used for unit tests.  In production%0A     * mode you are expected to manually create the table with the correct%0A     * length and field types.  See src/main/sql/*.sql for table definitions.%0A     */
 %0A   

Improve comment on Postgres/Hibernate @Lob issue