自定义Liferay服务功能无法openSession()

时间:2013-07-16 15:48:51

标签: java liferay portlet portal

这个问题让我很沮丧很长一段时间,我希望有人可以帮助我。我正在使用Service Builder将自定义实体公开给JSON Web Service API,我想在我的portlet中使用它。我不能使用动态查询,因为稍后会有几个更复杂的查询有多个连接,我觉得自定义sql是最好的选择。但是,我甚至无法开始查询,因为对openSession()的调用会抛出一个NPE。这是我的代码(我为长度道歉,但我真的不知道我在这里做错了什么,我只是想包括所有相关的内容):

ServiceImpl类:

@JSONWebService
public class MBMessagesAsDiscussionPrimeServiceImpl extends MBMessagesAsDiscussionPrimeServiceBaseImpl {
    @Override
    public List<MBMessagesAsDiscussionPrime> getMessagesAsDiscussionPrime() throws SystemException {
        MBMessagesAsDiscussionPrimeFinder finder = new MBMessagesAsDiscussionPrimeFinderImpl();
        return finder.findByGroupId();
    }
}

我的FinderImpl类:

public class MBMessagesAsDiscussionPrimeFinderImpl extends BasePersistenceImpl<MBMessagesAsDiscussionPrime> implements MBMessagesAsDiscussionPrimeFinder {

    @Override
    public List<MBMessagesAsDiscussionPrime> findByGroupId() throws SystemException {
        SessionFactory sessionFactory = (SessionFactory) PortalBeanLocatorUtil.locate("liferaySessionFactory");

        Session session = null;
        try {
            session = sessionFactory.openSession(); //exception here

            //other stuff here, eventually...
        } catch (Exception e) {
            throw new SystemException(e);
        } finally {
            closeSession(session); //throws NPE here
        }
    }
}

自定义查询:

<?xml version="1.0" encoding="UTF-8"?>
<custom-sql>
    <sql
        id="com.test.portlet.service.persistence.MBMessagesAsDiscussionPrimeFinder.findByGroupId">
        <![CDATA[
            SELECT * FROM MBMessage, MBThread
            WHERE
                (MBMessage.threadId = MBThread.threadId) AND
                (MBThread.groupID = ?) 
            ORDER BY
                MBThread.rootMessageId DESC, MBMessage.messageId ASC
        ]]>
    </sql>    
</custom-sql>

和service.xml:

<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC
"-//Liferay//DTD Service Builder 6.1.0//EN"
"http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">

<service-builder package-path="com.test.portlet">
    <namespace>MBMessagesAsDiscussionPrime</namespace>

    <entity name="MBMessagesAsDiscussionPrime" uuid="true" local-service="true" remote-service="true">

        <column name="messageId" type="long" primary="true" />
        <column name="threadId" type="long"/>
        <column name="userId" type="long"/>
        <column name="userName" type="String"/>
        <column name="body" type="String"/>

        <reference package-path="com.liferay.portlet.messageboards" entity="MBMessage" />
        <reference package-path="com.liferay.portlet.messageboards" entity="MBThread" />
    </entity>    
</service-builder>

从localhost:8080 / custom-query-portlet / api / jsonws可以看到服务功能,这是我从中调用它的地方。除了在ServiceImpl类上设置@JSONWebService之外,还有什么特别需要做的事情,因为这是远程调用的吗?拜托,有人帮我解决这个问题。它让我爬上了墙!

2 个答案:

答案 0 :(得分:0)

试试此代码

 @Override
    public List<MBMessagesAsDiscussionPrime> findByGroupId() throws SystemException {
        Session session = null;
        try {
            session = openSession();

            //other stuff here, eventually...
        } catch (Exception e) {
            throw new SystemException(e);
        } 
    }

HTH

答案 1 :(得分:0)

使用Liferay 6.1.20和构建我使用maven和Liferay插件版本6.2.10.9。

确保您的MBMessagesAsDiscussionPrimeFinderImpl类位于service.persistence包/文件夹中。

运行服务构建器时,它会为您的WhateverFinderImpl生成接口。在你的情况下MBMessagesAsDiscussionPrimeFinderImpl。另外,它添加了代码以将其实例化到WhateverLocalServiceImpl中。在您的情况下,它似乎是MBMessagesAsDiscussionPrimeServiceImpl。

如果您的MBMessagesAsDiscussionPrimeServiceImpl类等同于WhateverLocalServiceImpl,那么它应该已经在其中实例化了您的MBMessagesAsDiscussionPrimeFinderImpl类,并且您可以将代码更改为以下内容并且它将起作用。

public class PlayerService extends Service implements MediaPlayer.OnPreparedListener,
        MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnBufferingUpdateListener{

    private static final String ACTION_PLAY = "action.PLAY";
    private static final String ACTION_PAUSE = "action.PAUSE";
    private static final String ACTION_RESUME = "action.RESUME";
    private static final String ACTION_SEEK = "action.SEEK_TO";
    private static final String ACTION_NEXT = "action.NEXT";
    private static final String ACTION_PREVIOUS = "action.PREVIOUS";
    private static final String ACTION_REPEAT = "action.REPEAT";
    private MediaPlayer mediaPlayer = null;
    private String curentURL;
    private boolean repeat = false;
    private int currentPosition;

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("TEST", "Primesc comanda prin BroadcastReceiver " + intent.getAction());
            String action = intent.getAction();
            if(action.equals(ACTION_PLAY)){
                curentURL = intent.getStringExtra("musicURL");
                currentPosition = intent.getIntExtra("musicPosition", 0);
                try {
                    if(mediaPlayer.isPlaying()) {
                        mediaPlayer.stop();
                    }
                    mediaPlayer.reset();
                    mediaPlayer.setDataSource(intent.getStringExtra("musicURL"));
                    mediaPlayer.prepareAsync();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            else if(action.equals(ACTION_PAUSE)){
                if(mediaPlayer.isPlaying())
                    mediaPlayer.pause();
            } else if(action.equals(ACTION_RESUME)){
                if(!mediaPlayer.isPlaying())
                    mediaPlayer.start();
            } else if(action.equals(ACTION_SEEK)){
                if(mediaPlayer.isPlaying())
                    mediaPlayer.seekTo(intent.getIntExtra("seekProgress", 0) * 100);
                Log.i("TEST","Dau seek la "+intent.getIntExtra("seekProgress", 0));
            } else if(action.equals(ACTION_NEXT)){
                Intent nextIntent = new Intent("action.activity.NEXT");
                intent.putExtra("nextPosition", currentPosition+1);
                sendBroadcast(nextIntent);
            } else if(action.equals(ACTION_PREVIOUS)){
                Intent previousIntent = new Intent("action.activity.PREVIOUS");
                intent.putExtra("previousPosition", currentPosition-1);
                sendBroadcast(previousIntent);
            } else if(action.equals(ACTION_REPEAT)) {
                repeat = intent.getBooleanExtra("repeatStatus", false);
            }
        }
    };

    @Override
    public void onCreate() {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnErrorListener(this);
        mediaPlayer.setOnBufferingUpdateListener(this);

        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_PLAY);
        filter.addAction(ACTION_PAUSE);
        filter.addAction(ACTION_NEXT);
        filter.addAction(ACTION_RESUME);
        filter.addAction(ACTION_PREVIOUS);
        filter.addAction(ACTION_SEEK);
        filter.addAction(ACTION_REPEAT);
        registerReceiver(receiver, filter);

        Notification notification = new Notification(R.drawable.playlisticon, getText(R.string.ticker_text),
                System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, musicPlayer.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        notification.setLatestEventInfo(this, getText(R.string.notification_title),
                getText(R.string.notification_message), pendingIntent);
        startForeground(1337, notification);

        Log.i("TEST","onCreate se apeleaza");
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(receiver);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.i("TEST","A pornit service-ul");

        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("TEST", "Se face onBind");
        return null;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();

        Intent intent = new Intent("action.activity.UPDATE_UI");
        intent.putExtra("duration", mp.getDuration());
        sendBroadcast(intent);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {

        Log.i("TEST", "Eroare incerc din nou "+what+" "+extra);

        try {
            if(mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            mediaPlayer.reset();
            mediaPlayer.setDataSource(curentURL);
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        Log.i("TEST", "Action onComplete");

        if(repeat) {
            Intent intent = new Intent("action.activity.REPEAT");
            intent.putExtra("currentPosition", currentPosition);
            sendBroadcast(intent);
        } else {
            Intent intent = new Intent("action.activity.NEXT");
            intent.putExtra("nextPosition", currentPosition+1);
            sendBroadcast(intent);
        }
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {

        if(mediaPlayer.isPlaying()){
            Intent intent = new Intent("action.activity.UPDATE_BUFFER");
            intent.putExtra("progress", percent);
            intent.putExtra("seekBarProgress", mp.getCurrentPosition() / 100);
            intent.putExtra("mediaCurentPosition", mp.getCurrentPosition());
            sendBroadcast(intent);

            Log.i("TEST","Current Position = "+mp.getCurrentPosition());
        }
    }
}

对于mBMessagesAsDiscussionPrimeFinder,驼峰案例可能有所不同。