目前,我正在开发一个Java EE项目,其中包含有关持久性管理的一些非常重要的要求.用户对实体的更改首先需要在验证之前应用于某个工作副本,然后将它们应用于"实时数据".对实时数据的任何更改也需要有一些记录,以允许审计.
实体通过JPA进行管理,Hibernate将用作提供者.这是一个给定的,所以我们不回避Hibernate特定的东西.对于第一个要求,使用两个持久性单元.一个将实体映射到"实时数据"表,另一个映射到"工作副本"表.对于第二个要求,我们将使用Hibernate Envers,非常适合我们的用例.
到现在为止还挺好.现在,当用户在(基于Web的)前端查看数据时,能够指示工作副本中的哪些字段与实时数据相比更为有用.不同的颜色就足够了.为此,我们需要一些方法来了解哪些属性被改变了.我的问题是,有什么好办法可以解决这个问题?
使用JavaBeans API,PropertyChangeListener可以足以通知工作副本的实体中的任何更改并保留其中的一组.但是该集合也需要持久化,因为应用程序可以重新启动,并且在它们被验证并应用于实时数据之前,更改可以是长期的.并且在每次需要时应用实时数据的变化以获得工作副本是不可行的(因此两个持久性单元).我们还可以将工作副本与实时数据进行比较,并查找不同的字段.一些内省和反射代码就足够了,但这似乎相当于处理密集型,更不用说需要获取实时数据了.也许我错过了一些简单的东西,或者有人知道我可以使用的一个很棒的JPA/Hibernate功能.即使我无法避免制作(a)用于存储此类信息的单独数据库表,直到将其应用于实时数据,但这种方案的一些最佳实践或实际经验可能非常有用.
我意识到这是一个半开放的问题,但肯定其他人一定遇到过这样的要求.任何好的建议都值得赞赏,任何指向现成解决方案的指针都是接受答案的好候选人.
我有这样的绑定文件
<jxb:bindings version="2.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<jxb:bindings schemaLocation="example.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="example" />
</jxb:schemaBindings>
<jxb:globalBindings>
<jxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime"
printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
<jxb:javaType name="java.util.Calendar" xmlType="xs:date"
parseMethod="javax.xml.bind.DatatypeConverter.parseDate"
printMethod="javax.xml.bind.DatatypeConverter.printDate" />
<jxb:javaType name="java.util.Calendar" xmlType="xs:time"
parseMethod="javax.xml.bind.DatatypeConverter.parseTime"
printMethod="javax.xml.bind.DatatypeConverter.printTime" />
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>
Run Code Online (Sandbox Code Playgroud)
模式类在"example"(正确)中生成,但是"org.w3._2001.xmlschema"中的XmlAdapters(错误).我怎样才能解决这个问题?
我使用JAXB来使用这个API来方便地使用XJC(XML-to-Java)编译器通过命名引用从XML Schema生成的对象模型.它抽象了JAXB上下文的创建,并通过各种背景魔法和反射找到了ObjectFactory方法.它的基本要点是你总是定义一个通用模式,然后任何数字(也可能是0)模式"扩展"一般模式,每个模式产生自己的数据模型.通用模式带有可重用的定义,扩展它的定义使用它们来组成自己的模型.
我现在遇到了我想为多个项目重用通用模式的情况.一般类型定义应该在项目中保持相同,并且一些代码将针对从这些类生成的抽象类构建.所以我需要先为一些通用模式生成类,然后生成那些扩展并单独使用它们的类.我正在使用Maven进行构建过程.
我遇到的问题是从扩展模式中的通用模式解析类型定义.
假设我的通用模式名为"general.xsd",如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.foobar.com/general"
xmlns:gen="http://www.foobar.com/general"
elementFormDefault="qualified" attributeFormDefault="qualified">
<!-- Element (will usually be root) -->
<xs:element name="transmission" type="gen:Transmission" />
<!-- Definition -->
<xs:complexType name="Transmission" abstract="true">
<xs:sequence>
<!-- Generic parts of a transmission would be in here... -->
</xs:sequence>
</xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
接下来是一个绑定文件来做一些命名自定义并设置输出的包名称:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<!-- Bindings for the general schema -->
<bindings schemaLocation="general.xsd" node="/xs:schema">
<schemaBindings>
<package name="com.foobar.models.general"/>
</schemaBindings>
<bindings node="//xs:complexType[@name='Transmission']">
<!-- Some customization of property names here... …Run Code Online (Sandbox Code Playgroud) 很快,我们需要开发一个GUI来为我们的EAI解决方案创建配置(更像是脚本,说实话).想想典型的工作流编辑器.实际流程的可视化很可能是一个完全自定义的工作,无论是在Swing,SWT还是JavaFX 2.我选择的麻烦在于是自己做其他事情还是使用富客户端平台.
特别是,我注意到JavaFX 2受到了很多关注,并且似乎被Oracle推动为Java GUI领域的下一个重点.这些演示看起来很有趣,也许这个更新的API更专注于生产力,而不是Swing倾向于强加的大量样板代码.使用获得大量支持的新技术似乎是未来维护的安全选择.
使用RCP对这个项目有一定的好处.无论我们是以Eclipse还是NetBeans作为平台,拥有用于查看底层(XML)配置,版本控制等的现有插件/模块都能以最少的工作提供强大的功能.我也喜欢在同一个GUI中将Java项目旁边的软件项目类型包含在内的想法.即使是简单的东西,如窗口管理和自定义排列面板,RCP也可以更好地处理我们可以提供的东西.
那么现在的问题是,哪种技术或其组合是可行的?据我所知,我的选择是:
基本上我唯一的GUI体验是Swing上的小应用程序.这是我第一次寻找能保证RCP的东西.但JavaFX 2似乎是前进的方向,我不想错过那条船.如果Swing可能会出局,我宁愿跳上新技术.
如果有人可以分享他们的经验,尝试过像NetBeans + JavaFX 2这样的东西,或者更接近JavaFX的最前沿,并且可以推荐/阻止它用于我最感兴趣的这类事情.
我意识到这是一个有点开放的问题,但我真的不能想到一个更合适的地方.我不是在寻找"什么是最好的RCP/JavaFX比Swing更好"的辩论.我正在寻找在这种情况下使用/反对它们的有效点.
我们目前正在分析新版Java EE应用程序的技术要求.这是Java EE 6,但转到7是一个选项.到目前为止,这是一个单一的应用程序,一个EAR,提供定义明确的功能.但是,需要能够基于实现项目和/或客户以非常特定的方式定义某些功能.
例如,某些客户将具有非常特定的安全约束.可以显示框架处理的消息列表.对于一个客户,可以让用户看到所有内容,但另一个客户希望仅根据用户的组显示某些类型的消息.这是一个以特定于上下文的方式定义实现,调整核心功能的示例.另一个可能的要求是一些客户希望扩展给定的功能,增加新的可能性.这是可扩展的部分.
因此,有必要建立一个定义通用功能但具有可插拔部分的架构,以及扩展的可能性.在某些方面,我粗略地了解了如何处理这个问题.这个问题有一个完美适用于表示层的答案,我们将在JSF 2中做:如何创建模块化JSF 2.0应用程序?
我不太确定业务逻辑层,安全性等.我最初的想法是定义接口(几个外观)并在运行时或部署时找到实现.与服务提供商机制大致相同.可以提供默认实现,可以定义自定义实现.这确实感觉像是一种Java SE解决方案,我想知道我是否只是应用那些我熟悉的概念,如果没有更好的EE.我认为@Alternative注释有这样的目的.
另一种可能性是使用拦截器和装饰器.我不确定拦截器在日志记录,审计和其他不涉及核心业务逻辑的事情之外的用途有多大.装饰器似乎适合允许使用自定义功能扩展实现,也可能是可插拔部分.
有人可以提供一些见解,了解哪种解决方案最适合这一挑战的哪一部分?我应该将这些方法结合到问题域的各个部分吗?我有没有看到的可能性?
一个重要的要求:我们希望能够将特定于客户/项目的代码分开.我们不希望在每个实现的版本控制下拥有完整版本的应用程序,因为这将成为快速维护的噩梦.理想情况下,也没有必要将其构建为单片EAR,但能够将可插入部件添加到某些lib文件夹或单独部署它们.
草率的简短版本:
我的域模型中有各种表/实体,它们具有相同的字段(UUID).有一个表我需要将这些实体的行/实例链接到其他JPA管理的实体.换句话说,该链接表中的字段实例将不会被预先知道.我能想到的两种方法是:
@MappedSuperClass商店中的链接表中的实例的类的名称为好,或者类似的东西,让我定义逻辑右表中得到实际的实例.两者在复杂性和性能方面都有优点和缺点.您认为最好的是哪种,是否有第三种选择,或者您曾经尝试过类似的东西,并建议/强烈警告?
长版本,以防您想要更多背景:
我有一个数据库/对象模型,其中许多类型有一个共同的字段:通用唯一标识符(UUID).原因是这些类型的实例可能会发生变化.这些更改遵循命令模型,并且可以封装其数据并保持其自身.让我们把这种变化称为"变异".必须有可能找出数据库中存在哪些突变对于任何给定实体,反之亦然,存储突变在哪个实体上运行.
为了存储"突变",我们使用一个名为的表/实体MutationHolder.要将突变链接到其目标实体,有一个MutationEntityLink.这个数据没有直接MutationHolder关联的唯一原因是因为可以有直接或间接的链接,但这里的重要性不大,所以我把它排除在外:

问题归结为我如何为该entity领域建模MutationEntityLink.我能想到两种方法.
第一个是@Entity使用UUID字段创建一个带抽象注释的类.Customer,Contract并且Address将扩展它.所以这是一个TABLE_PER_CLASS策略.我假设我可以使用它作为entity场的类型,虽然我不确定.但是,我担心这可能会导致严重的性能损失,因为JPA需要查询许多表来查找实际的实例.
二是简单地使用@MappedSuperClass,只是存储UUID在实体entity领域MutationEntityLink.为了获得具有该UUID的实际实体,我必须以编程方式解决它.添加一个包含实体类名的附加列,或者允许我识别它或将其粘贴到JPQL查询中的其他内容.这需要更多的工作,但似乎更有效.如果需要,我不反对编写一些实用程序类或进行一些反射/自定义注释工作.
我的问题是哪种方法看起来最好?或者,您可能有更好的建议,或者注意到我遗漏了一些东西; 例如,也许有一种方法来添加一个类型列,即使使用TABLE_PER_CLASS继承将JPA指向右表?也许你已经尝试过这样的事情并且想要警告我可能出现的许多问题.
一些额外的信息:
在我工作的公司,我们有一个产品,所有意图和目的都可以称为咨询软件.它是EDI的平台,具有相当多的移动部件.后端是用Java SE编写的ESB,前端是在GlassFish上运行的Java EE应用程序,数据库通常在MSSQL服务器上,RabbitMQ用作排队中间件.从某种意义上说,它是域不可知的,可以部署不同的消息模型和映射.设置新环境往往需要相当长的时间,但很多是通过填写正确的参数和运行脚本可以轻松实现自动化的平凡任务.数据库的T-SQL,GlassFish上的asadmin脚本和ESB配置都是XML,因此模板上的XSLT转换可以完成这项工作.
这永远不会成为一个简单的安装,但拥有一个"安装程序",为您完成大部分工作,列出必备步骤,为用户提供一个方便的方式来提供必要的参数,生成一些脚本并放置到位对人好点; 即使只有开发者使用它,它也会让生活更轻松.虽然该软件在技术上与平台无关,但它往往在Windows Server上运行.
只是制作一个执行上述操作的Java应用程序并不是非常困难,而是重新发明轮子(并制作一个可能非常丑陋的GUI),我想看看是否有任何现有的解决方案符合要求.InstallShield和Inno Setup看起来很有前景.所以问题是,哪个现有工具可以提供以下内容,或者是从头开始制作一些值得的东西?
我们有一个应用程序,它有许多实体类,必须有两个表.表格相同,唯一的区别是名称.这里提供的常见解决方案是使用继承(映射的超类和每类表策略)或两个具有不同映射的持久性单元.我们使用后一种解决方案,应用程序是建立在这种方法之上的,所以它现在被认为是给定的.
EJB方法将在两个持久性上下文中进行更新,并且必须在一个事务中执行此操作.两个持久性上下文都具有相同的数据源,这是与Microsoft SQL Server数据库(2012版)的启用XA的连接.上下文之间的唯一区别是,有一个映射XML可以更改某些实体类的表名,从而适用于这些表.
其中一个架构主管希望看到XA事务被消除,因为它们会对数据库造成巨大的开销,并且显然也会使执行的查询的日志记录和分析更加困难,可能还会阻止一些预先准备好的语句缓存.我不知道所有的细节,但对于很多应用程序,我们已经成功地消除了XA.然而,对于这一个,我们目前不能因为两个持久化上下文.
在这种情况下是否有某种方法可以在没有XA的情况下以事务方式对两个上下文进行更新?如果是这样,怎么样?如果没有,是否可以使用一个持久化上下文进行架构或配置更改而不必转向两个表的子类?
我知道这些问题:是否可以在事务中使用多个持久性单元,而不是XA?和 两阶段提交的XA事务
在投票将其作为副本关闭之前,请注意情况不同.我们不像第一个问题那样处于只读状态,两个上下文都在同一个数据库上运行,我们只使用MSSQL而我们使用的是GlassFish,而不是Weblogic.
我正在尝试将EAR文件部署到Glassfish 5服务器。确切的版本是GlassFish Server Open Source Edition 5.0 (build 25)。部署是通过管理GUI完成的,并列出了已放置在域的applib文件夹中的另一个库。尝试部署时,它立即失败,并显示以下形式的消息Error occurred during deployment: java.io.IOException: invalid zip file: file:/C:/glassfish5/glassfish/tmp/(ear_file_name).ear. Please see server.log for more details.
文件名将是EAR文件的名称,后跟某种形式的时间戳或随机数。我检查了temp目录,可以看到在那里创建了一个0字节大小的EAR文件。最初,这是Windows temp文件夹,我怀疑有访问问题,因此我将JVM设置为对临时文件使用其他文件夹,如上所示。这也失败了。我尝试与具有管理员权限的用户一起运行Glassfish,但仍然无济于事。
如何解决这个问题?
附加信息:
asadmin提示符下使用deploy命令(或直接通过asadmin deploy --libraries=[jar in applibs] [ear file])通过命令行进行部署可以正常工作。部署时来自服务器的日志文件如下:
[2019-07-17T17:16:48.174+0200] [glassfish 5.0] [INFO] [] [org.glassfish.admingui] [tid: _ThreadID=46 _ThreadName=admin-listener(4)] [timeMillis: 1563376608174] [levelValue: 800] [[
GUI deployment: uploadToTempfile]]
[2019-07-17T17:16:48.175+0200] [glassfish 5.0] [INFO] [] [org.glassfish.admingui] [tid: _ThreadID=46 _ThreadName=admin-listener(4)] [timeMillis: 1563376608175] [levelValue: 800] [[
uploadFileName=Test-app-ear-3.0.0.0-SNAPSHOT.ear]]
[2019-07-17T17:16:48.177+0200] [glassfish 5.0] …Run Code Online (Sandbox Code Playgroud) TypeElement在注释处理器中获取a 时,您可以TypeMirror使用方法请求其超类(或更具体地说,它)getSuperClass().据的JavaDoc,一个类型不明确地延伸任何东西(换句话说,Object是超类),或者是一个接口将返回一个NoType带有NONE作为TypeKind.
无视整个模型/镜像API事物似乎不顾一切地让您在每个机会中迷惑一下这一事实,我将如何可靠地检查这一点?这是一些代码提取:
//Cast is safe since TypeKind is checked before this
final TypeElement el = (TypeElement)annotatedElement;
...
final TypeMirror parent = el.getSuperclass();
//Checking whether "nothing" is extended
if(parent.getKind().equals(TypeKind.NONE) && parent instanceof NoType) {
...
}
Run Code Online (Sandbox Code Playgroud)
这是正确的方式吗?看起来相当笨重.由于equalsTypeMirror的方法不应该用于语义相等性检查,我想知道它是否安全使用它TypeKind.我的直觉是肯定的,因为它是一个枚举,但后来我对此表示怀疑instanceof.
有没有更好的方法呢?整个javax.lang.model包及其子代在整个商店都有交叉引用,我从来都不清楚什么是最好的方法.对于某些东西有一些有用的实用方法,然后看似简单的任务需要如上所述的可疑杂技.
java ×6
java-ee ×3
jpa ×3
inheritance ×2
jaxb ×2
xjc ×2
audit ×1
deployment ×1
ear ×1
ejb ×1
enterprise ×1
glassfish ×1
hibernate ×1
installation ×1
installer ×1
java-ee-8 ×1
javabeans ×1
javafx-2 ×1
jaxb-episode ×1
maven ×1
mirror ×1
orm ×1
properties ×1
rcp ×1
sql-server ×1
swing ×1
xa ×1
xmlcatalog ×1