根据my own question我刚刚在Startup Singleton的PostConstruct中发现了数据初始化的另一个问题。该问题是由主键冲突引起的,该冲突是在以下期间生成的:
@Singleton
@Startup
public class DefaultDataIntializer {
@PostConstruct
public void init()
{
BlinkUser bu = createDefaultUser();
BlinkGroup bg = createDefaultGroup();
Link l = createDefaultLink();
UserLink ul = createDefaultUserLink();
if(buf.find(bu.getEmail()) != null)
return;
bg.addUser(bu);
ul.setLink(l);
ul.setOwner(bu);
lf.create(l);
bgf.create(bg);
buf.create(bu);
ulf.create(ul);
}
}
here是完整部署的日志。问题在于:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'user@gmail.com' for key 'PRIMARY'
但是当我使用调试器时,问题在创建过程中没有显示出来。也许是由一些缓存引起的?好吧,这是远景,我只是没有发现任何错误,特别是我在创建之前检查示例数据的存在(DefaultDataInitializer :: init():5)。另外,这是我的persistence.xml:
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="BlinkLinkServer-ejbPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/BlinkLinkDataSource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
也许某些交易有问题?我不应该这样初始化数据?谢谢你的帮助!
修改 根本原因是重复调用postConstruct方法。即使是同步或附加变量(甚至是静态的)也不能解决问题。甚至调试器也没有显示第二次调用(第二次没有在断点处停止)。那么我怎么弄清楚这是不同的方法呢?
public synchronized void init()
{
Logger.getAnonymousLogger().warning("Initializing data!" + (new Random()).nextInt());
//rest of previous code
}
给出了:
16:08:21,079 WARNING [null] (ServerService Thread Pool -- 424) Initializing data!778044534
16:08:21,116 WARNING [null] (ServerService Thread Pool -- 423) Initializing data!1060447455
答案 0 :(得分:0)
好的,所以此问题的真正原因是项目中的重复ejb jar - 一个在WAR中,另一个在EAR中打包。我不知道调试器怎么不让我进入@PostConstruct
方法的第二次调用。感谢TomasZ寻求帮助,我没有单独解决这个问题。
检查Maven项目。 WAR中的pom.xml
应具有依赖性:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>YourProject-ejb</artifactId>
<version>${project.version}</version>
</dependency>
据此,带有EJB项目的JAR文件被打包到WAR中。我相信你将拥有一个包含其他依赖项的EJB maven项目:
<dependency>
<groupId>com.example.project</groupId>
<artifactId>YourProject-ejb</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.example.project</groupId>
<artifactId>YourProject-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
所以还有JAR文件。它是错误的行为(我正在使用NetBeans,因此它是项目创建者的错误)。有一些方法可以避免这种情况:
将provided
范围添加到WAR项目中的pom.xml:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>YourProject-ejb</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
然后jar不会包含在WAR中。
为maven-war-plugin配置添加skinnyWar选项 described here
您可以出于某种原因希望将您的JAR文件保留在WAR中并从EAR中删除。因此,您可以简单地将提供的选项添加到EAR文件中的依赖项。
<dependency>
<groupId>com.example.project</groupId>
<artifactId>YourProject-ejb</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.example.project</groupId>
<artifactId>YourProject-web</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>