将 EJB 2.0 迁移到 EJB 3.x Web 应用程序忘记了较低层值
Migrating EJB 2.0 to EJB 3.x Web app forgets lower tier value
我目前正在尝试迁移一个 EAR 项目
-旧项目-
EJB 2.0
Jboss5.0.1
-新项目-
EJB 3.0
Wildfly 13.0.0Final
它是我设法创建的会话 bean,我可以调用它。它本身的逻辑似乎有效。我遇到的问题是后续行动之一似乎忘记了它在做什么。
我看到的当前问题如下:
在 class 的 Web 应用程序中,我们正在创建另一个 class 的对象,然后我们触发其父方法。然后,此父方法调用 class 并将其自身作为参数,然后检查它是哪种类型,然后根据类型为会话 bean 加注星标。然后在这个函数中调用参数函数 performExecute()
我们调用查询并实际获得正确的结果,然后我们将结果集值添加到私有 dto 成员。然后 performExecute 就完成了。然后我们回到 Web 应用程序 class,然后我们尝试使用 get 函数访问同一个 dto 成员。这个 returns 一个空指针。我想知道我是否忘记了我的会话 bean 中的某些内容?
旧会话bean:
public class TxNotSupportedCommandServerBean implements SessionBean {
SessionContext sessionContext;
public void ejbCreate() throws CreateException {}
public void ejbRemove() {
sessionContext = null;
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
public void executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
}
}
新的:
@Stateless
@Remote
@TransactionManagement(value=TransactionManagementType.CONTAINER)
@TransactionAttribute(value=REQUIRED)
public class TxNotSupportedCmdServerBean implements TxNotSupportedCmdServerRemote{
/**
* Default constructor.
*/
public TxNotSupportedCmdServerBean() {
// TODO Auto-generated constructor stub
}
public void executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
}
}
这两个都在 EJB.Jar
该接口在 EJBClient.jar
中实现
旧界面:
public interface TxNotSupportedCommandServerLocal extends EJBLocalObject {
public void executeCommand(TargetableCommand cmd) throws CommandException;
}
新界面:
public interface TxNotSupportedCmdServerRemote {
public void executeCommand(TargetableCommand cmd) throws CommandException;
}
下面是下一组文件,它们也在 EJBClient.jar
TargetableCommand:
public abstract class TargetableCommand implements Command {
private boolean constraintViolated;
protected RequestContext requestContext;
protected String dataSourceName;
public TargetableCommand(RequestContext requestContext, String dataSourceName) {
this.requestContext = requestContext;
this.dataSourceName = dataSourceName;
}
public TargetableCommand(RequestContext requestContext) {
this.requestContext = requestContext;
}
public TargetableCommand(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
public TargetableCommand() {
}
public void setConstraintViolated(boolean constraintViolated) {
this.constraintViolated = constraintViolated;
}
public boolean isConstraintViolated() {
return constraintViolated;
}
public abstract void performExecute() throws CommandException;
public void execute() throws CommandException {
CommandTarget.executeCommand(this);
}
}
命令:
public interface Command extends Serializable {
public void execute() throws CommandException;
}
注释的代码是旧的会话 bean。
命令目标:
public class CommandTarget {
public CommandTarget() {
}
/**
* Exekverar ett kommando i rätt miljö, t.ex. med eller utan transaktionshantering
* @param cmd TargetableCommand Kommandot som ska utföras
* @throws CommandException
*/
public static void executeCommand(TargetableCommand cmd) throws CommandException {
Context context = null;
try {
ServiceLocator sl = ServiceLocator.getInstance();
// if (cmd instanceof TxRequired) {
// TxRequiredCommandServerLocalHome cmdSrvHome = (TxRequiredCommandServerLocalHome) sl.getEJBLocalHome("TxRequiredCommandServer");
// TxRequiredCommandServerLocal cmdSrv = cmdSrvHome.create();
// cmdSrv.executeCommand(cmd);
// }
// else if(cmd instanceof TxNotSupported) {
// TxNotSupportedCommandServerLocalHome cmdSrvHome = (TxNotSupportedCommandServerLocalHome) sl.getEJBLocalHome("TxNotSupportedCommandServer");
// TxNotSupportedCommandServerLocal cmdSrv = cmdSrvHome.create();
// cmdSrv.executeCommand(cmd);
// }
// else {
// throw new CommandException("Cannot instanciate command server");
// }
//
System.out.println("CT: Inside commandTarget. about to diffrientate what instance");
context = JNDILookupClass.getInitialContext();
if (cmd instanceof TxRequired) {
System.out.println("CT: TxRequired");
TxRequiredCmdServerRemote cmdSrv = (TxRequiredCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxRequiredCmdServerRemoteBean", TxRequiredCmdServerRemote.class.getName()));
cmdSrv.executeCommand(cmd);
}
else if(cmd instanceof TxNotSupported) {
System.out.println("CT: TxNotSupported");
System.out.println("CT: cmd: " + cmd.getClass());
TxNotSupportedCmdServerRemote cmdSrv = (TxNotSupportedCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxNotSupportedCmdServerBean", TxNotSupportedCmdServerRemote.class.getName()));
cmdSrv.executeCommand(cmd);
}
else {
throw new CommandException("Cannot instanciate command server");
}
}
catch (CommandException ex) {
throw ex;
}
// catch (CreateException ex) {
// throw new CommandException(ex);
// }
//new catch
catch(NamingException ex) {
throw new CommandException(ex);
}
catch (ServiceLocatorException ex) {
throw new CommandException(ex);
}
}
}
呼...
好的,现在这就是 EJBClient 的重要部分。现在开始 Web.war
我只粘贴了实际运行的部分,它是 returns 一个空点
public class ActionIdentitetKonsultCommand implements Command {
private static Logger logger = Logger.getLogger(ActionIdentitetKonsultCommand.class);
public ActionIdentitetKonsultCommand() {
}
public String execute(RequestContext requestContext) throws CommandException {
GetPersonByPersnrEJBCommand personCmd;
logger.info("execute()");
try {
UserBean user = (UserBean) requestContext.getSession().getAttribute("user");
String kstnr = requestContext.getParameter("kstnr");
//Tilldela konsultuppgifter
personCmd = new GetPersonByPersnrEJBCommand();
personCmd.setPersnr(user.getPersnr());
System.out.println("AI: Before execute DTO " + personCmd.dto);
personCmd.execute();
System.out.println("AI: After execute DTO " + personCmd.dto);
logger.info("person hamtad med personnummer (EJB):");
logger.info(personCmd.getPerson().toString());
所以 personCmd.getPerson().tostring() 是导致空指针的原因。 GetPersonByPersnrEJBCommand():
public class GetPersonByPersnrEJBCommand extends TargetableCommand implements TxNotSupported {
public PersonDTO dto;
private long persnr;
public GetPersonByPersnrEJBCommand() {
}
public void setPersnr(long persnr) {
this.persnr = persnr;
}
public PersonDTO getPerson() {
return this.dto;
}
public void performExecute() throws CommandException {
try {
QueryPersonByPersnrCommand cmd = new QueryPersonByPersnrCommand();
cmd.setPersnr(persnr);
cmd.execute();
if(cmd.next()){
this.dto = new PersonDTO();
System.out.println("GP: inside PerformExecute DTO: " + dto);
dto.setPersnr(cmd.getPersnr());
dto.setEfternamn(cmd.getEfternamn());
dto.setFornamn(cmd.getFornamn());
dto.setEpostAdress(cmd.getEpostAdress());
dto.setKonsult((cmd.getKonsult() == 1));
dto.setAnsvarig((cmd.getAnsvarig() == 1));
System.out.println("GP: Inside Perform Execute DTO: " + dto);
}
}
catch (DataAccessCommandException ex) {
System.out.println("GetPersonByPersnrEJBCommand.performExecute misslyckades " + ex.getMessage());
throw new CommandException(ex);
}
}
}
就是这样;我不明白为什么它会忘记它。当我们在最后一个 class 中执行 sysouts 时,我们看到 dto 和 cmd 中都有数据,但是一旦函数结束,我们又回到调用它的 class 中,数据为空.
我怀疑它与我的会话 bean 有关,我缺少 属性 或其他东西。因为此代码适用于旧 JBOSS 服务器中的旧 bean。希望有人能帮助我,其他人也能从中学习。
我设法解决了这个问题。由于项目的范围是让它发挥作用。这不是一个漂亮的解决方案,如果有更多时间重写,这会更好。所以继续解决方案:
我们需要更改 bean、targetableCommand、CommandTarget 和 GetPersonByPersnrEJBCommand
TargetableCommand - 添加方法:
public TargetableCommand execute(TargetableCommand cmd) throws CommandException
{
return CommandTarget.executeCommand(cmd);
}
CommandTarget - 我们将方法 executeCommand 更改为 return 一个 TargetableCommand,并确保在 bean 完成后我们 return 该 cmd。
public static TargetableCommand executeCommand(TargetableCommand cmd) throws CommandException {
Context context = null;
try {
context = JNDILookupClass.getInitialContext();
if (cmd instanceof TxRequired) {
TxRequiredCmdServerRemote cmdSrv = (TxRequiredCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxRequiredCmdServerRemoteBean", TxRequiredCmdServerRemote.class.getName()));
cmd = cmdSrv.executeCommand(cmd);
}
else if(cmd instanceof TxNotSupported) {
TxNotSupportedCmdServerRemote cmdSrv = (TxNotSupportedCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxNotSupportedCmdServerBean", TxNotSupportedCmdServerRemote.class.getName()));
cmd = cmdSrv.executeCommand(cmd);
}
else {
throw new CommandException("Cannot instanciate command server");
}
}
catch (CommandException ex) {
throw ex;
}
catch(NamingException ex) {
throw new CommandException(ex);
}
}
return cmd;
}
bean - 将方法执行命令更改为 return Targetablecommand
public TargetableCommand executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd = cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
return cmd;
}
然后最后为了让它全部工作我不得不在 classes 中创建一个新方法来执行执行所以在 GetPersonByPersnrEJBCommand class 我创建了方法 wf13Layer( );这只是一个额外的步骤:
public void wf13Layer() throws CommandException
{
GetPersonByPersnrEJBCommand tmp;
try{
tmp = (GetPersonByPersnrEJBCommand) execute(this);
dto = tmp.getPerson();
} catch (Exception ex) {
throw new CommandException(ex);
}
}
这就是我为让它发挥作用所做的工作。正如我所说,这不是一个漂亮的解决方案,但它确实有效。 IT 似乎是一种组合,一旦我们在项目之间交叉,范围就会消失。为了进一步获得它,我们需要像这样对其进行分层。我真的希望这在某些时候对某人有所帮助,因为那里有很多旧代码 运行。
亲切的问候
很累
我目前正在尝试迁移一个 EAR 项目
-旧项目-
EJB 2.0
Jboss5.0.1
-新项目-
EJB 3.0
Wildfly 13.0.0Final
它是我设法创建的会话 bean,我可以调用它。它本身的逻辑似乎有效。我遇到的问题是后续行动之一似乎忘记了它在做什么。
我看到的当前问题如下:
在 class 的 Web 应用程序中,我们正在创建另一个 class 的对象,然后我们触发其父方法。然后,此父方法调用 class 并将其自身作为参数,然后检查它是哪种类型,然后根据类型为会话 bean 加注星标。然后在这个函数中调用参数函数 performExecute()
我们调用查询并实际获得正确的结果,然后我们将结果集值添加到私有 dto 成员。然后 performExecute 就完成了。然后我们回到 Web 应用程序 class,然后我们尝试使用 get 函数访问同一个 dto 成员。这个 returns 一个空指针。我想知道我是否忘记了我的会话 bean 中的某些内容?
旧会话bean:
public class TxNotSupportedCommandServerBean implements SessionBean {
SessionContext sessionContext;
public void ejbCreate() throws CreateException {}
public void ejbRemove() {
sessionContext = null;
}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
public void executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
}
}
新的:
@Stateless
@Remote
@TransactionManagement(value=TransactionManagementType.CONTAINER)
@TransactionAttribute(value=REQUIRED)
public class TxNotSupportedCmdServerBean implements TxNotSupportedCmdServerRemote{
/**
* Default constructor.
*/
public TxNotSupportedCmdServerBean() {
// TODO Auto-generated constructor stub
}
public void executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
}
}
这两个都在 EJB.Jar
该接口在 EJBClient.jar
中实现
旧界面:
public interface TxNotSupportedCommandServerLocal extends EJBLocalObject {
public void executeCommand(TargetableCommand cmd) throws CommandException;
}
新界面:
public interface TxNotSupportedCmdServerRemote {
public void executeCommand(TargetableCommand cmd) throws CommandException;
}
下面是下一组文件,它们也在 EJBClient.jar
TargetableCommand:
public abstract class TargetableCommand implements Command {
private boolean constraintViolated;
protected RequestContext requestContext;
protected String dataSourceName;
public TargetableCommand(RequestContext requestContext, String dataSourceName) {
this.requestContext = requestContext;
this.dataSourceName = dataSourceName;
}
public TargetableCommand(RequestContext requestContext) {
this.requestContext = requestContext;
}
public TargetableCommand(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
public TargetableCommand() {
}
public void setConstraintViolated(boolean constraintViolated) {
this.constraintViolated = constraintViolated;
}
public boolean isConstraintViolated() {
return constraintViolated;
}
public abstract void performExecute() throws CommandException;
public void execute() throws CommandException {
CommandTarget.executeCommand(this);
}
}
命令:
public interface Command extends Serializable {
public void execute() throws CommandException;
}
注释的代码是旧的会话 bean。
命令目标:
public class CommandTarget {
public CommandTarget() {
}
/**
* Exekverar ett kommando i rätt miljö, t.ex. med eller utan transaktionshantering
* @param cmd TargetableCommand Kommandot som ska utföras
* @throws CommandException
*/
public static void executeCommand(TargetableCommand cmd) throws CommandException {
Context context = null;
try {
ServiceLocator sl = ServiceLocator.getInstance();
// if (cmd instanceof TxRequired) {
// TxRequiredCommandServerLocalHome cmdSrvHome = (TxRequiredCommandServerLocalHome) sl.getEJBLocalHome("TxRequiredCommandServer");
// TxRequiredCommandServerLocal cmdSrv = cmdSrvHome.create();
// cmdSrv.executeCommand(cmd);
// }
// else if(cmd instanceof TxNotSupported) {
// TxNotSupportedCommandServerLocalHome cmdSrvHome = (TxNotSupportedCommandServerLocalHome) sl.getEJBLocalHome("TxNotSupportedCommandServer");
// TxNotSupportedCommandServerLocal cmdSrv = cmdSrvHome.create();
// cmdSrv.executeCommand(cmd);
// }
// else {
// throw new CommandException("Cannot instanciate command server");
// }
//
System.out.println("CT: Inside commandTarget. about to diffrientate what instance");
context = JNDILookupClass.getInitialContext();
if (cmd instanceof TxRequired) {
System.out.println("CT: TxRequired");
TxRequiredCmdServerRemote cmdSrv = (TxRequiredCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxRequiredCmdServerRemoteBean", TxRequiredCmdServerRemote.class.getName()));
cmdSrv.executeCommand(cmd);
}
else if(cmd instanceof TxNotSupported) {
System.out.println("CT: TxNotSupported");
System.out.println("CT: cmd: " + cmd.getClass());
TxNotSupportedCmdServerRemote cmdSrv = (TxNotSupportedCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxNotSupportedCmdServerBean", TxNotSupportedCmdServerRemote.class.getName()));
cmdSrv.executeCommand(cmd);
}
else {
throw new CommandException("Cannot instanciate command server");
}
}
catch (CommandException ex) {
throw ex;
}
// catch (CreateException ex) {
// throw new CommandException(ex);
// }
//new catch
catch(NamingException ex) {
throw new CommandException(ex);
}
catch (ServiceLocatorException ex) {
throw new CommandException(ex);
}
}
}
呼...
好的,现在这就是 EJBClient 的重要部分。现在开始 Web.war
我只粘贴了实际运行的部分,它是 returns 一个空点
public class ActionIdentitetKonsultCommand implements Command {
private static Logger logger = Logger.getLogger(ActionIdentitetKonsultCommand.class);
public ActionIdentitetKonsultCommand() {
}
public String execute(RequestContext requestContext) throws CommandException {
GetPersonByPersnrEJBCommand personCmd;
logger.info("execute()");
try {
UserBean user = (UserBean) requestContext.getSession().getAttribute("user");
String kstnr = requestContext.getParameter("kstnr");
//Tilldela konsultuppgifter
personCmd = new GetPersonByPersnrEJBCommand();
personCmd.setPersnr(user.getPersnr());
System.out.println("AI: Before execute DTO " + personCmd.dto);
personCmd.execute();
System.out.println("AI: After execute DTO " + personCmd.dto);
logger.info("person hamtad med personnummer (EJB):");
logger.info(personCmd.getPerson().toString());
所以 personCmd.getPerson().tostring() 是导致空指针的原因。 GetPersonByPersnrEJBCommand():
public class GetPersonByPersnrEJBCommand extends TargetableCommand implements TxNotSupported {
public PersonDTO dto;
private long persnr;
public GetPersonByPersnrEJBCommand() {
}
public void setPersnr(long persnr) {
this.persnr = persnr;
}
public PersonDTO getPerson() {
return this.dto;
}
public void performExecute() throws CommandException {
try {
QueryPersonByPersnrCommand cmd = new QueryPersonByPersnrCommand();
cmd.setPersnr(persnr);
cmd.execute();
if(cmd.next()){
this.dto = new PersonDTO();
System.out.println("GP: inside PerformExecute DTO: " + dto);
dto.setPersnr(cmd.getPersnr());
dto.setEfternamn(cmd.getEfternamn());
dto.setFornamn(cmd.getFornamn());
dto.setEpostAdress(cmd.getEpostAdress());
dto.setKonsult((cmd.getKonsult() == 1));
dto.setAnsvarig((cmd.getAnsvarig() == 1));
System.out.println("GP: Inside Perform Execute DTO: " + dto);
}
}
catch (DataAccessCommandException ex) {
System.out.println("GetPersonByPersnrEJBCommand.performExecute misslyckades " + ex.getMessage());
throw new CommandException(ex);
}
}
}
就是这样;我不明白为什么它会忘记它。当我们在最后一个 class 中执行 sysouts 时,我们看到 dto 和 cmd 中都有数据,但是一旦函数结束,我们又回到调用它的 class 中,数据为空. 我怀疑它与我的会话 bean 有关,我缺少 属性 或其他东西。因为此代码适用于旧 JBOSS 服务器中的旧 bean。希望有人能帮助我,其他人也能从中学习。
我设法解决了这个问题。由于项目的范围是让它发挥作用。这不是一个漂亮的解决方案,如果有更多时间重写,这会更好。所以继续解决方案: 我们需要更改 bean、targetableCommand、CommandTarget 和 GetPersonByPersnrEJBCommand
TargetableCommand - 添加方法:
public TargetableCommand execute(TargetableCommand cmd) throws CommandException
{
return CommandTarget.executeCommand(cmd);
}
CommandTarget - 我们将方法 executeCommand 更改为 return 一个 TargetableCommand,并确保在 bean 完成后我们 return 该 cmd。
public static TargetableCommand executeCommand(TargetableCommand cmd) throws CommandException {
Context context = null;
try {
context = JNDILookupClass.getInitialContext();
if (cmd instanceof TxRequired) {
TxRequiredCmdServerRemote cmdSrv = (TxRequiredCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxRequiredCmdServerRemoteBean", TxRequiredCmdServerRemote.class.getName()));
cmd = cmdSrv.executeCommand(cmd);
}
else if(cmd instanceof TxNotSupported) {
TxNotSupportedCmdServerRemote cmdSrv = (TxNotSupportedCmdServerRemote)context.lookup(JNDILookupClass.getLookupName("TxNotSupportedCmdServerBean", TxNotSupportedCmdServerRemote.class.getName()));
cmd = cmdSrv.executeCommand(cmd);
}
else {
throw new CommandException("Cannot instanciate command server");
}
}
catch (CommandException ex) {
throw ex;
}
catch(NamingException ex) {
throw new CommandException(ex);
}
}
return cmd;
}
bean - 将方法执行命令更改为 return Targetablecommand
public TargetableCommand executeCommand(TargetableCommand cmd) throws CommandException {
try {
cmd = cmd.performExecute();
}
catch (CommandException ex) {
throw ex;
}
return cmd;
}
然后最后为了让它全部工作我不得不在 classes 中创建一个新方法来执行执行所以在 GetPersonByPersnrEJBCommand class 我创建了方法 wf13Layer( );这只是一个额外的步骤:
public void wf13Layer() throws CommandException
{
GetPersonByPersnrEJBCommand tmp;
try{
tmp = (GetPersonByPersnrEJBCommand) execute(this);
dto = tmp.getPerson();
} catch (Exception ex) {
throw new CommandException(ex);
}
}
这就是我为让它发挥作用所做的工作。正如我所说,这不是一个漂亮的解决方案,但它确实有效。 IT 似乎是一种组合,一旦我们在项目之间交叉,范围就会消失。为了进一步获得它,我们需要像这样对其进行分层。我真的希望这在某些时候对某人有所帮助,因为那里有很多旧代码 运行。
亲切的问候 很累