Dodawanie ofert do bazy - Postresql, błąd zapisywania się

0

Cześć! Mam problem z zapisywaniem nowego rekrdu do bazy. Wpisuję oldValue, currentValue, offerCommentText i otrzymuję komunikat o pustej wartości offer_id, który powinien być generowany automatycznie. Załączam mój Offer model, OfferController w którym znajduje się metoda dodająca ofertę oraz komunikat z GlassFisha. Może ktoś z Was może mi doradzić i powiedzieć gdzie popełniłem błąd?

@Entity
@Table(name = "offer")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Offer.findAll", query = "SELECT o FROM Offer o")
    , @NamedQuery(name = "Offer.findByOfferId", query = "SELECT o FROM Offer o WHERE o.offerId = :offerId")
    , @NamedQuery(name = "Offer.findByCurrentValue", query = "SELECT o FROM Offer o WHERE o.currentValue = :currentValue")
    , @NamedQuery(name = "Offer.findByOldValue", query = "SELECT o FROM Offer o WHERE o.oldValue = :oldValue")
    , @NamedQuery(name = "Offer.findByOfferCommentText", query = "SELECT o FROM Offer o WHERE o.offerCommentText = :offerCommentText")
    , @NamedQuery(name = "Offer.findByOfferCreatingTime", query = "SELECT o FROM Offer o WHERE o.offerCreatingTime = :offerCreatingTime")})
public class Offer implements Serializable {


    private static final long serialVersionUID = 1L;
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false)
//    @Column(name = "offer_id", nullable = false)
    private Integer offerId;
    @Basic(optional = false)
    @NotNull 
    @Column(name = "current_value")
    private int currentValue;
    @Basic(optional = false)
    @NotNull
    @Column(name = "old_value")
    private int oldValue;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 254)
    @Column(name = "offer_comment_text")
    private String offerCommentText;
    @Column(name = "offer_creating_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date offerCreatingTime;
    @JoinColumn(name = "order_id", referencedColumnName = "order_id")
    @ManyToOne(optional = false)
    private Order1 orderId;
    @JoinColumn(name = "user_id", referencedColumnName = "user_id")
    @ManyToOne(optional = false)
    private UserAccount userId;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "offerId")
    private List<Comment> commentList;
//    @OneToMany(cascade = CascadeType.ALL, mappedBy = "offerId")
//    private Comment comment;

    public Offer() {
    }

    public Offer(Integer offerId, int currentValue, int oldValue, String offerCommentText, Date offerCreatingTime) {
        this.offerId = offerId;
        this.currentValue = currentValue;
        this.oldValue = oldValue;
        this.offerCommentText = offerCommentText; 
        this.offerCreatingTime = offerCreatingTime;
    }

@Named("offerController")
@SessionScoped
public class OfferController implements Serializable { 
    
    private String offerCommentText; 
    private int selectedOfferIndex;  
    private List<String> offerList; 
    private Integer offerId;
    private int curentValue; 
    private int oldValue; 
    private Offer selectedOffer = new Offer();   
    
    @Inject 
    private OfferServiceImpl offerService;

   //Gettery, settery
    
      public void addOffer() {
        Offer offerToAdd= selectedOffer;
        offerToAdd.setOfferCommentText(offerCommentText); 
        offerToAdd.setOldValue(oldValue); 
        offerToAdd.setCurrentValue(curentValue);
        offerToAdd.setOfferCreatingTime(new Date());
        offerService.create(offerToAdd);
    }   
}

javax.ejb.EJBException: Transaction aborted

(...)
Internal Exception: org.postgresql.util.PSQLException: BŁĄD: pusta wartość w kolumnie "offer_id" narusza ograniczenie wymaganej wartości
  Szczegóły: Niepoprawne ograniczenia wiersza (null, null, null, 3, 3, ffff, 2018-11-09 14:50:35.525).
Error Code: 0
Call: INSERT INTO offer (current_value, offer_comment_text, offer_creating_time, old_value, order_id, user_id) VALUES (?, ?, ?, ?, ?, ?)
	bind => [6 parameters bound]
Query: InsertObjectQuery(model.Offer[ offerId=null ])
	at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1611)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:898)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
	at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
	at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
	at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
	at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
	at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
	at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
	at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
	at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
	at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
	at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
	at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
	at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226)
	at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125)
	at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4207)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3168)
	at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:352)
	at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:158)
	... 78 more
Caused by: org.postgresql.util.PSQLException: BŁĄD: pusta wartość w kolumnie "offer_id" narusza ograniczenie wymaganej wartości
  Szczegóły: Niepoprawne ograniczenia wiersza (null, null, null, 3, 3, rrrr, 2018-11-09 15:04:08.908).
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2477)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2190)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:300)
	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
	at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:169)
	at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:136)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:424)
	at com.sun.proxy.$Proxy316.executeUpdate(Unknown Source)
	at com.sun.gjc.spi.base.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:125)
	at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
0

A ta adnotacja nie jest czasami potrzebna?

//    @Column(name = "offer_id", nullable = false)
    private Integer offerId;
0

Powiem Ci, że zakomentowałem to żeby zobaczyć czy będzie działało, już pomysłu nie miałem, myślałem, ze może to z tym nullem coś nie tak ale zakomentowane czy nie - działa identycznie.

0

A jaki komunikat błędu leci po odkomentowaniu?

Edit: czy id generujesz sekwencją czy masz serial na kolumnie?
Jeżeli sekwencją to powinieneś wykorzystać @SequenceGenerator.

0

Po odkomentowaniu tej linijki komunikat jest taki sam.

Korzystam z postgresql i w pgAdminie jakos nie mogę ustawić komulmny serial ;/ ale mam tak samo zrobioną już inną tabele i wszystko jest ok.

0

Ok, a pokaż jak wygląda definicja tabeli z ofertami i dla porównania tabeli na której działa inkrementacja.

0

Ok, załączam jak to wygląda w pgAdminie - offer i order1, tam mi się dodaje id normalnie.

0

Niestety nie znam się na pgAdminie, więc ktoś inny musiałby spojrzeć. Sprawdź czy w typach kolumn jest serial i przetestuj jako id oferty.

Pytanie dlaczego dla order działa? Może tam ręcznie jest ustawiane id przed insertem? Pokaz mapping order do kompletu :)

0

Pokaż importy w encji i co robi Twój service jak wrzucasz obiekt do create?
Czemu w ogóle tworzysz obiekt w polu kontrolera? wtf? Powinieneś go tworzyć w metodzie która ustawia Ci właściwości tego obiektu a nie w polu

0
Seti87 napisał(a):

Niestety nie znam się na pgAdminie, więc ktoś inny musiałby spojrzeć. Sprawdź czy w typach kolumn jest serial i przetestuj jako id oferty.

Pytanie dlaczego dla order działa? Może tam ręcznie jest ustawiane id przed insertem? Pokaz mapping order do kompletu :)

Ok, to podsyłam order :)

@Entity
@Table(name = "order1")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Order1.findAll", query = "SELECT o FROM Order1 o")
    , @NamedQuery(name = "Order1.findByOrderId", query = "SELECT o FROM Order1 o WHERE o.orderId = :orderId")
    , @NamedQuery(name = "Order1.findByName", query = "SELECT o FROM Order1 o WHERE o.name = :name")
    , @NamedQuery(name = "Order1.findByCreateTime", query = "SELECT o FROM Order1 o WHERE o.createTime = :createTime")
    , @NamedQuery(name = "Order1.findByBodyForm", query = "SELECT o FROM Order1 o WHERE o.bodyForm = :bodyForm")
    , @NamedQuery(name = "Order1.findByDescription", query = "SELECT o FROM Order1 o WHERE o.description = :description")
    , @NamedQuery(name = "Order1.findByCapacity", query = "SELECT o FROM Order1 o WHERE o.capacity = :capacity")
    , @NamedQuery(name = "Order1.findByUnit", query = "SELECT o FROM Order1 o WHERE o.unit = :unit")
    , @NamedQuery(name = "Order1.findByBudget", query = "SELECT o FROM Order1 o WHERE o.budget = :budget")
    , @NamedQuery(name = "Order1.findByCurrency", query = "SELECT o FROM Order1 o WHERE o.currency = :currency")
    , @NamedQuery(name = "Order1.findByOrderLength", query = "SELECT o FROM Order1 o WHERE o.orderLength = :orderLength")
    , @NamedQuery(name = "Order1.findByOrderWidth", query = "SELECT o FROM Order1 o WHERE o.orderWidth = :orderWidth")
    , @NamedQuery(name = "Order1.findByOrderHeight", query = "SELECT o FROM Order1 o WHERE o.orderHeight = :orderHeight")
    , @NamedQuery(name = "Order1.findByPickupDate", query = "SELECT o FROM Order1 o WHERE o.pickupDate = :pickupDate")
    , @NamedQuery(name = "Order1.findByDeliveryDate", query = "SELECT o FROM Order1 o WHERE o.deliveryDate = :deliveryDate")
    , @NamedQuery(name = "Order1.findByExpirationDate", query = "SELECT o FROM Order1 o WHERE o.expirationDate = :expirationDate")
    , @NamedQuery(name = "Order1.findByUser", query = "SELECT o FROM Order1 o INNER JOIN o.userHasOrderList uhl WHERE uhl.user.userId = :userAccountId")
    , @NamedQuery(name = "Order1.findByLodeType", query = "SELECT o FROM Order1 o WHERE o.lodeType = :lodeType")})
public class Order1 implements Serializable {


    @OneToMany(cascade = CascadeType.ALL, mappedBy = "orderId")
    private List<Offer> offerList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "order1")
    private List<UserHasOrder> userHasOrderList; 
   

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "order_id")
    private Integer orderId;
    @Size(max = 45)
    @Column(name = "name")
    private String name;
    @Basic(optional = false)
    @NotNull
    @Column(name = "create_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "body_form")
    private String bodyForm;
    @Size(max = 255)
    @Column(name = "description")
    private String description;
    @Column(name = "capacity")
    private Integer capacity;
    @Size(max = 3)
    @Column(name = "unit")
    private String unit;
    // @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
    @Column(name = "budget")
    private BigDecimal budget;
    @Size(max = 3)
    @Column(name = "currency")
    private String currency;
    @Column(name = "order_length")
    private Integer orderLength;
    @Column(name = "order_width")
    private Integer orderWidth;
    @Column(name = "order_height")
    private Integer orderHeight;
    @Column(name = "pickup_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date pickupDate;
    @Column(name = "delivery_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date deliveryDate;
    @Column(name = "expiration_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date expirationDate;
    @Size(max = 45)
    @Column(name = "lode_type")
    private String lodeType;
    @JoinColumn(name = "delivery_address", referencedColumnName = "order_address_id")
    @ManyToOne(optional = false)
    private OrderAddress deliveryAddress;
    @JoinColumn(name = "pickup_address", referencedColumnName = "order_address_id")
    @ManyToOne(optional = false)
    private OrderAddress pickupAddress;
    @JoinColumn(name = "status", referencedColumnName = "order_status_id")
    @ManyToOne(optional = false)
    private OrderStatus status; 
    @ManyToMany(mappedBy = "order1List")
    private List<LoadingType> loadingTypeList;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "order1")
    private List<OrderHasParameter> orderHasParameterList;  
    @JoinColumn(name = "user_id", referencedColumnName = "user_id")
    @ManyToOne
    private UserAccount userId;
0
OtoKamil napisał(a):

Pokaż importy w encji i co robi Twój service jak wrzucasz obiekt do create?
Czemu w ogóle tworzysz obiekt w polu kontrolera? wtf? Powinieneś go tworzyć w metodzie która ustawia Ci właściwości tego obiektu a nie w polu

Projekt odziedziczyłem po kimś i już z braku pomysłów zacząłem robić tak jak ten ktoś wcześniej, wiem, że to slabo ale za bardzo nie mam pomocy znikąd i już na różne sposoby probowałem.

Tu jest offer:

package model;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author Sharpeo
 */
@Entity
@Table(name = "offer")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Offer.findAll", query = "SELECT o FROM Offer o")
    , @NamedQuery(name = "Offer.findByOfferId", query = "SELECT o FROM Offer o WHERE o.offerId = :offerId")
    , @NamedQuery(name = "Offer.findByCurrentValue", query = "SELECT o FROM Offer o WHERE o.currentValue = :currentValue")
    , @NamedQuery(name = "Offer.findByOldValue", query = "SELECT o FROM Offer o WHERE o.oldValue = :oldValue")
    , @NamedQuery(name = "Offer.findByOfferCommentText", query = "SELECT o FROM Offer o WHERE o.offerCommentText = :offerCommentText")
    , @NamedQuery(name = "Offer.findByOfferCreatingTime", query = "SELECT o FROM Offer o WHERE o.offerCreatingTime = :offerCreatingTime")})
public class Offer implements Serializable {


    private static final long serialVersionUID = 1L;
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false)
    @Column(name = "offer_id", nullable = false)
    private Integer offerId;
    @Basic(optional = false)
    @NotNull 
    @Column(name = "current_value")
    private int currentValue;
    @Basic(optional = false)
    @NotNull
    @Column(name = "old_value")
    private int oldValue;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 254)
    @Column(name = "offer_comment_text")
    private String offerCommentText;
    @Column(name = "offer_creating_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date offerCreatingTime;
    @JoinColumn(name = "order_id", referencedColumnName = "order_id")
    @ManyToOne(optional = false)
    private Order1 orderId;
    @JoinColumn(name = "user_id", referencedColumnName = "user_id")
    @ManyToOne(optional = false)
    private UserAccount userId;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "offerId")
    private List<Comment> commentList;

a service tak wygląda:

package service.impl;

import dao.impl.OfferDaoImpl;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Inject;
import model.Offer;
import model.UserAccount;

@LocalBean 
@Stateless
public class OfferServiceImpl { 
    
    
    @Inject
    public UserAccountServiceImpl userAccountService;   
    
    @Inject
    public OfferDaoImpl offerDao;  
    
    
      public Offer chosenOffer(Integer id) {
        return offerDao.findById(id);
    }
    
    
//    @Override 
    public List<String> offerList() { 
        List <String> offerList = new ArrayList<>(); 
        
        return offerList;                
    }  
    
    public void create(Offer offer){
        offerDao.create(offer);
    }

    public void edit(Offer offer) { 
      offerDao.edit(offer);
    }
//    return userHasOrderDao.edit(userHasOrder);
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1