Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » NullPointerException when using flush()
NullPointerException when using flush() [message #1568166] Fri, 16 January 2015 20:11 Go to next message
Chris Neeser is currently offline Chris NeeserFriend
Messages: 5
Registered: August 2011
Junior Member
I am having an intermittent issue and I can't seem to nail down why it's happening. I have a EJB application that uses JPA (Eclipselink 2.3.2), which is implemented using web services. All of the beans are stateless. Every so often, when a user executes the web service responsible for refreshing information in the database, an exception is thrown. The specific line of code that causes the error to be thrown is "em.flush()". I'm hoping that someone can look at my code below, perhaps there is a problem with my implementation.

I have also seen the problem happen when I attempt to issue a remove() followed by a flush(). Any help would be much appreciated!

exception:
ERROR [com.onsemi.cim.qmserver] ClientIP=172.16.108.30, Operation=compare, Exception= [ java.lang.NullPointerException ] nulljava.lang.NullPointerException

	at java.util.TreeMap.compare(TreeMap.java:1188)
	at java.util.TreeMap.put(TreeMap.java:531)
	at org.eclipse.persistence.internal.sessions.CommitManager.sort(CommitManager.java:351)
	at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:312)
	at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:288)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1418)
	at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:636)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1561)
	at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:447)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:780)
	at com.sun.enterprise.container.common.impl.EntityManagerWrapper.flush(EntityManagerWrapper.java:418)
	at com.onsemi.cim.LotManager.LotManager.updateLot(LotManager.java:417)
	at com.onsemi.cim.LotManager.LotManager.getLots(LotManager.java:315)
	at com.onsemi.cim.qmserver.LotManagement.getLots(LotManagement.java:189)
	at sun.reflect.GeneratedMethodAccessor170.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
	at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
	at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
	at sun.reflect.GeneratedMethodAccessor156.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
	at com.sun.ejb.containers.WebServiceInvocationHandler.invoke(WebServiceInvocationHandler.java:192)
	at $Proxy247.getLots(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor169.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.glassfish.webservices.InvokerImpl.invoke(InvokerImpl.java:82)
	at org.glassfish.webservices.EjbInvokerImpl.invoke(EjbInvokerImpl.java:82)
	at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:149)
	at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:94)
	at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
	at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
	at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
	at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
	at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:116)
	at org.glassfish.webservices.MonitoringPipe.process(MonitoringPipe.java:142)
	at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
	at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
	at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
	at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
	at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
	at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:116)
	at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.processRequest(CommonServerSecurityPipe.java:212)
	at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.process(CommonServerSecurityPipe.java:144)
	at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
	at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
	at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
	at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
	at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
	at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:386)
	at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:640)
	at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:263)
	at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:163)
	at org.glassfish.webservices.Ejb3MessageDispatcher.handlePost(Ejb3MessageDispatcher.java:120)
	at org.glassfish.webservices.Ejb3MessageDispatcher.invoke(Ejb3MessageDispatcher.java:91)
	at org.glassfish.webservices.EjbWebServiceServlet.dispatchToEjbEndpoint(EjbWebServiceServlet.java:200)
	at org.glassfish.webservices.EjbWebServiceServlet.service(EjbWebServiceServlet.java:131)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
	at com.sun.grizzly.http.servlet.ServletAdapter$FilterChainImpl.doFilter(ServletAdapter.java:1059)
	at com.sun.grizzly.http.servlet.ServletAdapter$FilterChainImpl.invokeFilterChain(ServletAdapter.java:999)
	at com.sun.grizzly.http.servlet.ServletAdapter.doService(ServletAdapter.java:434)
	at com.sun.grizzly.http.servlet.ServletAdapter.service(ServletAdapter.java:384)
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
	at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
	at java.lang.Thread.run(Thread.java:722)


This is the code that causes the error, specifically the "em.flush":
public Lot updateLot(String lotId, String stationId, String rackName, String rackPosition) throws Exception
    {
        //Get the current list of recipes so we can compare to the new list to get the record id's
        //If there are new recipes they will be added to the table.
        Lot lot = getLot(lotId);
        List<LotEquipRecipe> oldLERList = lot.getLotEquipRecipes();
        
        lot = lde.getLotData(lotId);
        
        //reset the rackid and position
        lot = setLotLocationInfo(lot,stationId,rackName,rackPosition);
        
        String lotStatus = "";
        boolean updateLotFlag = false;
        
        try
        {
            if(lot.getLotStatus() != null)
                lotStatus = lot.getLotStatus();

            if(lotStatus.equals("RUN"))
            {
                //Remove the lot from the rack
                removeLot(lotId, null);

                //Set the log message and log to the database
                String message = "Lot " + lotId + " has entered a RUN state and has been removed from rack " + stationId + "!";
                dbe.saveLogEntry(stationId, "INFO", message);

                //Log to the file and also set the error on the lot so that it is reported back to the client.
                logger.info(message);
                lot.setError("The lot is in a run state and has been removed from the rack!");
            }
            else
            {   
                //Check to see if we are still in a wait state, the data may have changed if the lot was manipulated in PROMIS above.
                if(lot.getLotStatus().equals("WAIT"))
                {
                    //Check to see if lot should be re-routed and re-route it
                    if(processReroute(lot))
                        updateLotFlag = true;

                    //Check to see if we need to place this lot on hold
                    if(processRestrictedLot(lot))
                        updateLotFlag = true;
                }
                
                //If the lot info changed because of re-route or the lot being put on hold then update the lot info.
                if(updateLotFlag == true)
                    lot = lde.getLotData(lotId);
                
                //Set the lot color if the lot is supposed to go to the annex
                if(lot.getAnnexFlag() == 1)
                    lot.setColor("191,107,255/145,0,255");
                
                //reset the rackid and position
                lot = setLotLocationInfo(lot,stationId,rackName,rackPosition);

                //Identify rows
                List<LotEquipRecipe> newLERList = lot.getLotEquipRecipes();
                if(newLERList != null)
                {
                    for(int x = 0; x < newLERList.size(); x++)
                    {
                        for(int y = 0; y < oldLERList.size(); y++)
                        {
                            //Only check to see if they match if neither is null to avoid nullpointerexception
                            if(newLERList.get(x) != null && oldLERList.get(y) != null)
                            {
                                if(newLERList.get(x).getEquipRecipeOption().equals(oldLERList.get(y).getEquipRecipeOption()))
                                {
                                    newLERList.get(x).setRecordId(oldLERList.get(y).getRecordId());
                                }
                            }
                        }
                    }
                }
                
                //setLotColor(lot);
                em.merge(lot);
                em.flush();
            }
        }
        catch (Exception e)
        {
            throw(e);
        }
        return lot;
    }


The two entities at play here are as follows:
Lot
package com.onsemi.cim.LotManager;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;

@Entity(name = "Lot")
@Table(name = "LOT")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Lot.findAll", query = "SELECT distinct l FROM Lot l left join fetch l.lotEquipRecipes")})
public class Lot implements Serializable {
    @Id //Primary Key
    @Column(name = "lot_id", nullable=false)
    private String              lotId;

    @Column(name = "position")
    private String              lotRackPosition;

    @Column(name = "hostname")
    private String              hostName;

//    @Column(name = "recipe")
//    private ArrayList<String>   recipeList;

    @Column(name = "lottype")
    private String              lotType;

    @Column(name = "eqtype")
    private String              eqpType;

    @Column(name = "wafercount")
    private int                 waferCount;

    @Column(name = "stage")
    private String              stageName;

    @Column(name = "state")
    private String              state;

    @Column(name = "queuetime")
    private String              queTime;

//    @Column(name = "equipment")
//    private ArrayList<String>   equipRestrictList;

    @Column(name = "priority")
    private int                 lotPriority;

    @Column(name = "steps")
    private int                 stepsPerDay;

    @Column(name = "status")
    private String              lotStatus;

    @Column(name = "location")
    private String              promisLocation;

    @Column(name = "partid")
    private String              partId;

    @Column(name = "holdreason")
    private String              holdReason;

    @Column(name = "color")
    private String              color;

    @Column(name = "stepperRestr")
    private String              stepperRestr;

    @Column(name = "error")
    private String              error;

    @Column(name = "alphaphotomodes")
    private String              alphaPhotoModes;

    @Column(name = "automatedrecipeid")
    private String              automatedRecipeId;

    @Column(name = "amu")
    private String              amu;
    
    @Column(name = "dispatchable")
    private int             dispatchable;
    
    @Column(name = "restricted")
    private int             restricted;
    
    @Column(name = "rackname")
    private String              rackName;
    
    @Column(name = "expirytimer")
    private String              expiryTimer;
    
    @Column(name = "stagedAt")
    private String              stagedAt;
    
    @Column(name = "probecard")
    private String              probeCard;
    
    @OneToMany(mappedBy="lot", orphanRemoval=true, fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    private List<LotEquipRecipe> lotEquipRecipes;
    
    //Non-Database Managed Fields
    @Transient
    private String specRecpId;
    
    @Transient
    private int annexFlag;
    
    @Transient
    private int messageHandlingLevel;

    public int getMessageHandlingLevel() {
        return messageHandlingLevel;
    }

    public void setMessageHandlingLevel(int messageHandlingLevel) {
        this.messageHandlingLevel = messageHandlingLevel;
    }

    public String getProbeCard() {
        return probeCard;
    }

    public void setProbeCard(String probeCard) {
        this.probeCard = probeCard;
    }  
    
    public int getAnnexFlag() {
        return annexFlag;
    }

    public void setAnnexFlag(int annexFlag) {
        this.annexFlag = annexFlag;
    }

    public String getSpecRecpId() {
        return specRecpId;
    }

    public void setSpecRecpId(String specRecipId) {
        this.specRecpId = specRecipId;
    }

    public List<LotEquipRecipe> getLotEquipRecipes() {
        return lotEquipRecipes;
    }

    public void setLotEquipRecipes(List<LotEquipRecipe> lotEquipRecipes) {
        this.lotEquipRecipes = lotEquipRecipes;
    }

    public String getStagedAt() {
        return stagedAt;
    }

    public void setStagedAt(String stagedAt) {
        this.stagedAt = stagedAt;
    }
    
    public String getExpiryTimer() {
        return expiryTimer;
    }

    public void setExpiryTimer(String expiryTimer) {
        this.expiryTimer = expiryTimer;
    }
    
    public String getRackName() {
        return rackName;
    }

    public void setRackName(String rackName) {
        this.rackName = rackName;
    }
    
    public int getRestricted() {
        return restricted;
    }

    public void setRestricted(int restricted) {
        this.restricted = restricted;
    }
    
    public int getDispatchable() {
        return dispatchable;
    }

    public void setDispatchable(int dispatchable) {
        this.dispatchable = dispatchable;
    }

    public String getAmu() {
        return amu;
    }

    public void setAmu(String amu) {
        this.amu = amu;
    }

    public String getAutomatedRecipeId() {
        return automatedRecipeId;
    }

    public void setAutomatedRecipeId(String automatedRecipeId) {
        this.automatedRecipeId = automatedRecipeId;
    }

    public String getAlphaPhotoModes() {
        return alphaPhotoModes;
    }

    public void setAlphaPhotoModes(String alphaPhotoModes) {
        this.alphaPhotoModes = alphaPhotoModes;
    }

    public String getStepperRestr() {
        return stepperRestr;
    }

    public void setStepperRestr(String stepperRestr) {
        this.stepperRestr = stepperRestr;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }
    
    public String getLotType() {
        return lotType;
    }

    public void setLotType(String lotType) {
        this.lotType = lotType;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    
    public String getEqpType() {
        return eqpType;
    }

    public void setEqpType(String eqpType) {
        this.eqpType = eqpType;
    }

    public String getHoldReason() {
        return holdReason;
    }

    public void setHoldReason(String holdReason) {
        this.holdReason = holdReason;
    }

    public String getLotId() {
        return lotId;
    }

    public void setLotId(String lotId) {
        this.lotId = lotId;
    }

    public int getLotPriority() {
        return lotPriority;
    }

    public void setLotPriority(int lotPriority) {
        this.lotPriority = lotPriority;
    }

    public String getLotRackPosition() {
        return lotRackPosition;
    }

    public void setLotRackPosition(String lotRackPosition) {
        this.lotRackPosition = lotRackPosition;
    }

    public String getLotStatus() {
        return lotStatus;
    }

    public void setLotStatus(String lotStatus) {
        this.lotStatus = lotStatus;
    }

    public String getPartId() {
        return partId;
    }

    public void setPartId(String partId) {
        this.partId = partId;
    }

    public String getPromisLocation() {
        return promisLocation;
    }

    public void setPromisLocation(String promisLocation) {
        this.promisLocation = promisLocation;
    }

    public String getQueTime() {
        return queTime;
    }

    public void setQueTime(String queTime) {
        this.queTime = queTime;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String rackName) {
        this.hostName = rackName;
    }

    public String getStageName() {
        return stageName;
    }

    public void setStageName(String stageName) {
        this.stageName = stageName;
    }

    public int getStepsPerDay() {
        return stepsPerDay;
    }

    public void setStepsPerDay(int stepsPerDay) {
        this.stepsPerDay = stepsPerDay;
    }

    public int getWaferCount() {
        return waferCount;
    }

    public void setWaferCount(int waferCount) {
        this.waferCount = waferCount;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    
}


LotEquipRecipe
package com.onsemi.cim.LotManager;

import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

@Entity(name = "LotEquipRecipe")
@Table(name = "LOT_EQUIP_RECIPE")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "LotEquipRecipe.findAll", query = "SELECT l FROM LotEquipRecipe l"),
    @NamedQuery(name = "LotEquipRecipe.findByRecordId", query = "SELECT l FROM LotEquipRecipe l WHERE l.recordId = :recordId"),
    @NamedQuery(name = "LotEquipRecipe.findByLotId", query = "SELECT l FROM LotEquipRecipe l WHERE l.lotId = :lotId"),
    @NamedQuery(name = "LotEquipRecipe.findByEquipRecipeOption", query = "SELECT l FROM LotEquipRecipe l WHERE l.equipRecipeOption = :equipRecipeOption")})
public class LotEquipRecipe implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "RECORD_ID")
    @SequenceGenerator(name="lot_equip_recipe_seq", sequenceName="lot_equip_recipe_seq")
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="lot_equip_recipe_seq")

    private Integer recordId;
    @Size(max = 10)
    @Column(name = "LOT_ID")
    private String lotId;
    @Size(max = 100)
    @Column(name = "EQUIP_RECIPE_OPTION")
    private String equipRecipeOption;
    
    @ManyToOne
    @JoinColumn(name="LOT_ID", insertable=false, updatable=false)
    private Lot lot;

    public Lot getLot() {
        return lot;
    }

    public LotEquipRecipe() {
    }

    public LotEquipRecipe(Integer recordId) {
        this.recordId = recordId;
    }

    public Integer getRecordId() {
        return recordId;
    }

    public void setRecordId(Integer recordId) {
        this.recordId = recordId;
    }

    public String getLotId() {
        return lotId;
    }

    public void setLotId(String lotId) {
        this.lotId = lotId;
    }

    public String getEquipRecipeOption() {
        return equipRecipeOption;
    }

    public void setEquipRecipeOption(String equipRecipeOption) {
        this.equipRecipeOption = equipRecipeOption;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (recordId != null ? recordId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof LotEquipRecipe)) {
            return false;
        }
        LotEquipRecipe other = (LotEquipRecipe) object;
        if ((this.recordId == null && other.recordId != null) || (this.recordId != null && !this.recordId.equals(other.recordId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=" + recordId + " ]";
    }
    
}

[Updated on: Fri, 16 January 2015 20:14]

Report message to a moderator

Re: NullPointerException when using flush() [message #1573337 is a reply to message #1568166] Mon, 19 January 2015 17:38 Go to previous messageGo to next message
Rick Curtis is currently offline Rick CurtisFriend
Messages: 24
Registered: September 2014
Location: Rochester, MN
Junior Member
I spent just a few minutes looking at the code and the the NPE is coming from attempting to add an element to a TreeSet with a null key[1]. Is it possible that one of the elements that you're trying to remove doesn't have a PK set? ... I'm not sure if that makes much sense, but hopefully it'll help you narrow in on what is causing problems.

[1] :351 sortedObjects.put(objectBuilder.extractPrimaryKeyFromObject(objectToDelete, session), objectToDelete); // extractPrimaryKeyFromObject(...) returns null.
Re: NullPointerException when using flush() [message #1575332 is a reply to message #1573337] Tue, 20 January 2015 19:22 Go to previous messageGo to next message
Chris Neeser is currently offline Chris NeeserFriend
Messages: 5
Registered: August 2011
Junior Member
Thanks for the reply. I took your advice and on the exception I printed out the object that I am attempting to persist, you can see that here:

lotId=D35175.1
lotRackPosition=2,2,2
hostName=cque026x
lotType=PS
eqpType=CPDECIDE
waferCount=12
stageName=xxx
state=D
queTime=20-JAN-2015 12:12:11.00
lotPriority=5
stepsPerDay=7
lotStatus=WAIT
promisLocation=C-PHOTO
partId=xxx
holdReason= 
color=null
stepperRestr=
error=null
alphaPhotoModes=null
automatedRecipeId=xxx
amu=null
dispatchable=1
restricted=0
rackName=Right Rack
expiryTimer=null
stagedAt=null
probeCard=2400
lotEquipRecipes=[com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=null ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181137 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=null ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=null ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181133 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=null ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181128 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181138 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181178 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181136 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181132 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181179 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181129 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181127 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181134 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181135 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181131 ], com.onsemi.cim.LotManager.LotEquipRecipe[ recordId=79181130 ]]
specRecpId=CPA01
annexFlag=0
messageHandlingLevel=0
serialVersionUID=2802091524634182149
_persistence_primaryKey=D35175.1
_persistence_listener=null
_persistence_fetchGroup=null
_persistence_shouldRefreshFetchGroup=false
_persistence_session=null
 


You can see that LotEquipRecipes has a number of items listed (This is my child table), the first two items have a null recordId, which is the primary key. This means that these records need to be added. I have a sequence setup in the database and there is a trigger setup to automatically fill that in on insert. When you issue a merge, does it expect you to be updating all records, even the child tables?

[Updated on: Tue, 20 January 2015 19:24]

Report message to a moderator

Re: NullPointerException when using flush() [message #1575465 is a reply to message #1575332] Tue, 20 January 2015 21:00 Go to previous messageGo to next message
Rick Curtis is currently offline Rick CurtisFriend
Messages: 24
Registered: September 2014
Location: Rochester, MN
Junior Member
> I have a sequence setup in the database and there is a trigger setup to automatically fill that in on insert.
I don't follow your entire scenario, but this comment jumps out at me. I suspect that EclipseLink is caching the LotEquipRecipes with a null ID which then causes this problem. Try doing a refresh(or something) after the merge (on Entities with a null id) to get the L1/L2 cache(s) populated with the proper values.

> When you issue a merge, does it expect you to be updating all records, even the child tables?
When you issue a merge on a given Entity, all relationships marked as cascadeType MERGE OR ALL will also be merged.
Re: NullPointerException when using flush() [message #1575573 is a reply to message #1575465] Tue, 20 January 2015 22:29 Go to previous messageGo to next message
Chris Neeser is currently offline Chris NeeserFriend
Messages: 5
Registered: August 2011
Junior Member
I'm giving what you recommend a shot. I've deployed my change to production, just waiting for some data to roll in. I want to explain sort of what is going on here.

In the update function I have a the child table that I am updating, this is the basic logic.

1. get old recipe list from database and put it into variable oldLERList
2. execute function to return the new list (it may have changed).
3. loop through the new list, comparing each value to values in oldLERList, if a match is found, set the recordId in the new list to what the recordId was in the old list. (I do this so that I don't keep consuming id's each time I refresh).
4. set the lotEquipRecipes attribute in the main Lot entity.
5. merge the Lot entity.

Does this make sense? Am I over complicating this, or doing anything wrong as far as you can tell?
Re: NullPointerException when using flush() [message #1575836 is a reply to message #1575573] Wed, 21 January 2015 01:59 Go to previous messageGo to next message
Chris Neeser is currently offline Chris NeeserFriend
Messages: 5
Registered: August 2011
Junior Member
So after a lot of debugging and banging my head against the wall I think I figured out what was causing the problems.

The LotEquipRecipe entity uses an @GeneratedValue for the primary key. I had misunderstood how this actually worked. In the database I was using a sequence with an INSERT trigger in conjunction with the @GeneratedValue annotation. This was not the right way to go, because what was happening was Eclipselink was retrieving a value from the sequence and assigning it to the record, then when the record was inserted into the database, the trigger would grab a new record id from the sequence and apply it to the record. This confused the hell out of Eclipselink as it didn't have an accurate idea as to what the right record id was.

It's actually amazing the application worked as well as it did like this. In any case as soon as I disabled the database trigger things started working as they should. I appreciate your help on this!
Re: NullPointerException when using flush() [message #1576758 is a reply to message #1575836] Wed, 21 January 2015 14:05 Go to previous message
Rick Curtis is currently offline Rick CurtisFriend
Messages: 24
Registered: September 2014
Location: Rochester, MN
Junior Member
I'm glad you were able to get things straightened out!
Previous Topic:UUIDConverter and eclipselink 2.5.2
Next Topic:Lifecycle callbacks (preRemove, postRemove) not called on orphan removal
Goto Forum:
  


Current Time: Tue Apr 23 05:08:41 GMT 2024

Powered by FUDForum. Page generated in 0.04000 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top