我们的数据模型在两个数据库中分为模式.这些模式是隔离使用的,除了在两者之间桥接的一些单键关系.没有跨两个数据库的写入事务.
与此问题类似,使用Hibernate在不同数据库中对2个表进行连接,我们希望使用Hibernate来处理实体的连接.我们不能使用数据库解决方案(DB2上的联合视图).
我们已经使用两个独立的数据库配置(Doctor和Patient)设置了Hibernate,这在使用DAO显式访问特定会话时非常有效.
我们希望在调用时使用Hibernate自动检索实体DoctorBO.getExam().getPatient()Where检查包含指向另一个数据库上Patient表的id.
我尝试这样做的一种方法是使用自定义UserType:
public class DistributedUserType implements UserType, ParameterizedType
{
public static final String CLASS = "CLASS";
public static final String SESSION = "SESSION";
private Class<? extends DistributedEntity> returnedClass;
private String session;
/** {@inheritDoc} */
@Override
public int[] sqlTypes()
{
// The column will only be the id
return new int[] { java.sql.Types.BIGINT };
}
/** {@inheritDoc} */
@Override
public Class<? extends DistributedEntity> returnedClass()
{
// Set by typedef parameter
return returnedClass;
}
/** …Run Code Online (Sandbox Code Playgroud) 我正在使用Maven 3构建一个包含3层的java应用程序 - server,ejb和ui.EJB项目依赖于Server项目,UI项目仅依赖于EJB,并提供Server传递依赖项的排除.
当UI项目构建为战争时,尽管没有出现依赖:tree命令,但仍包含服务器依赖项.
这是运行的相关输出 mvn dependency:tree
**project.name:UI:war:1.0 SNAPSHOT**
+- project.name:Common:jar:1.0 SNAPSHOT:compile
| + org_common:_lib:jar:16.0.006:compile
| | +- log4j:log4j:jar:1.2.16:compile
| | \- commons configuration:commons configuration:jar:1.6:compile
| | +- commons lang:commons lang:jar:2.4:compile
| | +- commons digester:commons digester:jar:1.8:compile
| | \- commons beanutils:commons beanutils core:jar:1.8.0:compile
| +- org_common:_security_lib:jar:16.0.006:compile
| \- org.springframework:spring:jar:2.0:compile
+- **project.name:EJB:ejb client:client:1.0 SNAPSHOT:compile**
| \- com.ibm.websphere.appserver:j2ee:jar:7.0.0.9:compile
+- org_common:_uicomponent:jar:16.0.006:compile
Run Code Online (Sandbox Code Playgroud)
这是运行时的输出依赖树 mvn clean install -X
**project.name:UI:war:1.0 SNAPSHOT**
+- project.name:Common:jar:1.0 SNAPSHOT:compile
| + org_common:_lib:jar:16.0.006:compile
| | +- log4j:log4j:jar:1.2.16:compile
| | \- …Run Code Online (Sandbox Code Playgroud) 我有一个部署在两个EAR中的java Web应用程序 - 一个用于UI层(包含WAR模块),另一个用于业务层(包含EJB模块).这两个层都部署到WebSphere Application Server 7.这些层通过EJB 3.0无状态会话bean连接.通过JNDI查找bean.
我们使用Hibernate来实现持久性和DB2数据库.
返回远程EJB调用时,客户端发生以下错误:
java.rmi.MarshalException: CORBA MARSHAL 0x4942f896 No; nested exception is:
org.omg.CORBA.MARSHAL: Unable to read value from underlying bridge : Mismatched serialization UIDs : Source (RepId RMI:java.util.Date:AC117E28FE36587A:686A81014B597419) = 686A81014B597419 whereas Target (RepId RMI:com.ibm.db2.jcc.DBTimestamp:AA774DBE96ECCE99:7AFCE1FB570D419C) = 7AFCE1FB570D419C vmcid: IBM minor code: 896 completed: No
Run Code Online (Sandbox Code Playgroud)
的java.util.Date对象上字段被从休眠返回作为com.ibm.db2.jcc.DBTimestamp字段,其延伸java.sql.Timestamp,其延伸java.util.Date.因为它是java.util.Date可序列化的子类,所以不应该这样处理吗?
我和一位经验丰富的人谈过,他说可能的原因是DBTimestampWeb和业务层WAS服务器之间的JVM版本或类版本不同.两台服务器都具有相同的JVM,WAS和JAR版本.
我还有一个本地WAS 7服务器,其中两个层都部署到同一台服务器.仍然通过对localhost的JNDI调用远程解析EJB.该应用程序在我的本地服务器上运行正常 我所知道的唯一区别是WAS的不同微版本,以及将这两个层部署到同一台服务器.
问题的原因是什么?是DBTimestamp在Web层上找不到类,还是类的版本不同?或者它是多态性的问题,还是完全不同的东西?
除了答案之外,我还要感谢任何有关调试的建议 - 我没有想法.
我的问题非常类似于当字符串为空但不为空时如何防止在JAXB中编组空标记
不同之处在于我无法将注释添加到package-info.java,因为我们所有的JAXB类型都是从每次构建的模式生成的.如果可能的话,我也更愿意不更改JAXB提供程序.
我想要实现的是设置一个空String不会创建该元素,但我需要为许多模式中的所有生成的JAXB类型设置它.有没有办法将它应用于所有生成的JAXB类中的所有String字段?
更新 我已设法通过进行以下更改来为模式中的所有字符串生成XML适配器:
在项目POM中,我将其添加到maven-jaxb2-plugin:
<bindingDirectory>src/main/resources</bindingDirectory>
<bindingIncludes>
<include>bindings.xjb</include>
</bindingIncludes>
Run Code Online (Sandbox Code Playgroud)
这是我的bindings.xjb文件:
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
<jxb:globalBindings>
<jxb:javaType name="java.lang.String" xmlType="xs:token"
parseMethod="com.project.Formatter.parseString"
printMethod="com.project.Formatter.printString"/>
</jxb:globalBindings>
</jxb:bindings>
Run Code Online (Sandbox Code Playgroud)
和格式化方法:
public static String printString(final String value)
{
if (StringUtils.isBlank(value))
{
return null;
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
问题是这会导致JAXB内部出现空指针异常.这是堆栈跟踪:
Caused by: java.lang.NullPointerException
at com.sun.xml.bind.v2.runtime.output.SAXOutput.text(SAXOutput.java:158)
at com.sun.xml.bind.v2.runtime.XMLSerializer.leafElement(XMLSerializer.java:321)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:210)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$1.writeLeafElement(RuntimeBuiltinLeafInfoImpl.java:209)
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:250)
at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:98)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:65)
at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:168)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:152)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:322)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:681)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:150)
at …Run Code Online (Sandbox Code Playgroud) 我们实现了一个自定义配置工厂,以便以编程方式配置 Log4J2:
ConfigurationFactory.setConfigurationFactory(new MyConfigurationFactory());
Run Code Online (Sandbox Code Playgroud)
初始配置工作正常。
我们的代码中有某些侦听器可以触发全局“刷新配置”事件。发生这种情况时,我们需要完全重新配置 Log4J。
我尝试了多种选项来告诉 Log4J“重新配置”,但没有一个选项能够使用新配置充分重新创建 Appender。
这是我发现的最接近的东西,但它不适用于 Appender 配置:
ConfigurationFactory.setConfigurationFactory(new MyConfigurationFactory());
LoggerContext ctx = (LoggerContext) LogManager.getContext();
ctx.reconfigure();
ctx.updateLoggers();
Run Code Online (Sandbox Code Playgroud)
如何在 Log4J2 中触发全局重新配置事件,以便它删除整个配置,然后完全配置自身?
编辑:经过进一步调查和调试,记录器配置似乎也没有更新。记录器的初始级别设置保持不变。org.apache.logging.log4j.core.Logger.PrivateConfig不构造不可变类的新实例。
编辑2:我已经设法实现了一个有效的解决方案,但是实现很糟糕,我只能假设这是偶然的而不是设计的:
LoggerContext ctx = (LoggerContext) ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).getContext();
for(org.apache.logging.log4j.core.Logger l : ctx.getLoggers())
{
l.getContext().onChange((Reconfigurable) ctx.getConfiguration());
}
ctx.reconfigure();
Run Code Online (Sandbox Code Playgroud)
我的工作是实现一个通用框架来支持编程重新配置,因此实现不脆弱/有缺陷非常重要。我希望有一种正确的方法来完全重新配置 Log4J2,而不是像这样的代码,我会认为这是一种黑客攻击。
编辑 3:解决方案:根据下面接受的答案,我已将代码更改为以下内容:
ConfigurationFactory configFactory = new MyConfigurationFactory();
ConfigurationFactory.setConfigurationFactory(configFactory);
org.apache.logging.log4j.core.LoggerContext ctx = (org.apache.logging.log4j.core.LoggerContext) LogManager
.getContext(false);
ctx.start(configFactory.getConfiguration(ConfigurationSource.NULL_SOURCE));
Run Code Online (Sandbox Code Playgroud)