Spring引导:数据加载应用程序无法持久化hibernate/JPA
我的主要目标是尽可能多地利用Spring Boot应用程序基础结构,在经过大量处理后读取文件并将一些对象持久化到数据库中。问题是处理发生了,找到了DAO并执行了entityManager.save(),但没有对象被持久化(没有运行hibernate SQL) 这是我的加载工具应用程序(可能是错误的): 关联的属性文件:Spring引导:数据加载应用程序无法持久化hibernate/JPA,hibernate,jpa,spring-boot,Hibernate,Jpa,Spring Boot,我的主要目标是尽可能多地利用Spring Boot应用程序基础结构,在经过大量处理后读取文件并将一些对象持久化到数据库中。问题是处理发生了,找到了DAO并执行了entityManager.save(),但没有对象被持久化(没有运行hibernate SQL) 这是我的加载工具应用程序(可能是错误的): 关联的属性文件: # jdbc jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/xx
# jdbc
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xxxxxxpoint?autoReconnect=true
jdbc.user=root
jdbc.pass=password
# hibernate
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=verify
正如我所说,当所有这些都运行时,没有错误,也没有持久性。顺便说一句,我为pom(属性下)提供了主要的应用程序类:
<start-class>com.xxxxxcorp.xxxxxpoint.Application</start-class>
com.xxxxxcorp.xxxxxpoint.Application
所以我确信我不会启动两个上下文或两个应用程序或其他类似的东西。有人能告诉我哪里出了问题吗?当您的导入程序运行时,没有事务处于活动状态。您应该将其设置为
@Bean
,并标记其importContent()
方法@Transactional
。从CommandlineRunner
调用该方法
此外,如果您的“主要目的是尽可能多地利用Spring Boot应用程序基础架构”,那么为什么不扔掉其余的JPA和
数据源配置(它在启动时几乎是逐字节复制的)?我想我应该发回有效的解决方案。基本上我说的课错了…错了。感谢David Syer的回答
以下是修改后的ContentImporting应用程序:
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.touchcorp.touchpoint"})
public class ContentImportingApplication {
@Autowired
private VoucherTemplateDao voucherTemplateDao;
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(ContentImportingApplication.class);
ApplicationContext ctx = app.run(args);
ContentImporter importer = (ContentImporter) ctx.getBean("contentImporter");
importer.importContent(ctx);
System.exit(0);
}
@Bean
public ContentImporter contentImporter()
{
return new ContentImporter();
}
public class ContentImporter {
@Transactional
public void importContent(ApplicationContext ctx) throws Exception {
String otc = readFileAsString("content-to-import", ctx);
SAXBuilder sb = new SAXBuilder();
Document jDom = sb.build(new StringReader(otc));
// first step: associate products to otc documents
Map<Long,String> productDocumentNames = new HashMap<Long,String>();
Map<Long,String> productDocuments = new HashMap<Long,String>();
XPathExpression<Element> xpath = XPathFactory.instance().compile("//t", Filters.element());
List<Element> ts = xpath.evaluate(jDom);
for (Element t : ts) {
String documentName = t.getAttributeValue("d");
String productId = t.getChild("p").getChild("id").getValue();
// put it in, if there is a voucher for this product
if( documentName != null) {
productDocumentNames.put(Long.valueOf(productId), documentName);
} else {
System.out.println("No voucher associated with productId: " + productId);
}
}
List<Element> ds = jDom.getRootElement().getChildren("d");
for (Element d : ds) {
// for each document we find, we'll replace the document name with the content
String documentName = d.getAttributeValue("k");
Set<Long> productIds = productDocumentNames.keySet();
for(Long productId : productIds) {
if( productDocumentNames.get( productId ).equals( documentName ) ) {
findAndReplaceNestedDocs( jDom, d );
productDocuments.put( productId, new XMLOutputter( ).outputString( d.getContent() ) );
}
}
}
Set<Long> productIds = productDocuments.keySet();
for(Long productId : productIds) {
VoucherTemplate vt = VoucherTemplate.make(productId, "RETAILER_GROUP:*|CHANNEL:*|LOCALE:de-AT|INDUSTRY:5499", VoucherTemplate.TemplateSchema.OTC);
vt.setTemplate(productDocuments.get( productId ));
voucherTemplateDao.save(vt);
}
jDom.getRootElement().addContent( new Element("w") );
}
private void findAndReplaceNestedDocs(Document jDom, Element documentInOtcContent) {
// find the nested docs
List<Element> directives = documentInOtcContent.getChildren("w");
// and replace them
for(Element directive : directives) {
List<Element> docs = jDom.getRootElement().getChildren("d");
for (Element doc : docs) {
if (directive.getAttributeValue("d").equals(doc.getAttributeValue("k"))) {
List<Element> docContents = doc.getChildren();
List<Element> clones = new ArrayList<Element>();
for(Element docContent : docContents) {
Element docContentCopy = docContent.clone();
docContentCopy.detach();
clones.add(docContentCopy);
}
if (documentInOtcContent.indexOf(directive) != -1) {
documentInOtcContent.setContent(documentInOtcContent.indexOf(directive), clones);
}
}
}
break;
}
}
public String readFileAsString(String name, ApplicationContext ctx) {
String output = null;
// working code in here
return output;
}
}
}
@配置
@启用自动配置
@ComponentScan(basePackages={“com.touchcorp.touchpoint”})
公共类内容导入应用程序{
@自动连线
私人VoucherTemplateDao VoucherTemplateDao;
公共静态void main(字符串[]args)引发异常{
SpringApplication app=新的SpringApplication(ContentImportingApplication.class);
ApplicationContext ctx=app.run(args);
ContentImporter=(ContentImporter)ctx.getBean(“ContentImporter”);
进口商。进口内容(ctx);
系统出口(0);
}
@豆子
公共内容导入器内容导入器()
{
返回新的ContentImporter();
}
公共类内容导入器{
@交易的
public void导入内容(ApplicationContext ctx)引发异常{
字符串otc=readFileAsString(“要导入的内容”,ctx);
SAXBuilder sb=新SAXBuilder();
文档jDom=sb.build(新StringReader(otc));
//第一步:将产品关联到otc文档
Map productDocumentNames=新HashMap();
Map productDocuments=newhashmap();
XPathExpression xpath=XPathFactory.instance().compile(“//t”,Filters.element());
List ts=xpath.evaluate(jDom);
用于(元素t:ts){
字符串documentName=t.getAttributeValue(“d”);
字符串productId=t.getChild(“p”).getChild(“id”).getValue();
//如果有此产品的凭证,请将其放入
if(documentName!=null){
productDocumentNames.put(Long.valueOf(productId),documentName);
}否则{
System.out.println(“没有与productId:+productId关联的凭证”);
}
}
List ds=jDom.getRootElement().getChildren(“d”);
用于(元素d:ds){
//对于找到的每个文档,我们将用内容替换文档名称
字符串documentName=d.getAttributeValue(“k”);
Set productId=productDocumentNames.keySet();
for(长productId:productId){
if(productDocumentName.get(productId).equals(documentName)){
查找和替换嵌套的DOC(jDom,d);
put(productId,新的XMLOutputter().outputString(d.getContent());
}
}
}
Set productId=productDocuments.keySet();
for(长productId:productId){
VoucherTemplate vt=VoucherTemplate.make(productId,“零售商|集团:*|渠道:*|地区:de AT |行业:5499”,VoucherTemplate.TemplateSchema.OTC);
vt.setTemplate(productDocuments.get(productId));
voucherTemplateDao.save(vt);
}
jDom.getRootElement().addContent(新元素(“w”));
}
私有void findAndReplaceNestedDocs(文档jDom、元素documentInOtcContent){
//查找嵌套文档
列表指令=documentInotContent.getChildren(“w”);
//并替换它们
for(元素指令:指令){
List docs=jDom.getRootElement().getChildren(“d”);
用于(要素单据:单据){
如果(指令getAttributeValue(“d”)等于(文件getAttributeValue(“k”)){
List docContents=doc.getChildren();
列表克隆=新建ArrayList();
for(元素docContent:docContents){
元素docContentCopy=docContent.clone();
docContentCopy.detach();
克隆。添加(docContentCopy);
}
if(documentInOtcContent.indexOf(指令)!=-1){
DocumentInotContent.setContent(DocumentInotContent.indexOf(指令),克隆);
}
}
}
打破
}
}
公共字符串readFileAsString(字符串名称,ApplicationContext ctx){
字符串输出=null;
//这里的工作代码
返回输出;
}
}
}
我不确定我是否完全理解你的第二点。我想我不需要
<start-class>com.xxxxxcorp.xxxxxpoint.Application</start-class>
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.touchcorp.touchpoint"})
public class ContentImportingApplication {
@Autowired
private VoucherTemplateDao voucherTemplateDao;
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(ContentImportingApplication.class);
ApplicationContext ctx = app.run(args);
ContentImporter importer = (ContentImporter) ctx.getBean("contentImporter");
importer.importContent(ctx);
System.exit(0);
}
@Bean
public ContentImporter contentImporter()
{
return new ContentImporter();
}
public class ContentImporter {
@Transactional
public void importContent(ApplicationContext ctx) throws Exception {
String otc = readFileAsString("content-to-import", ctx);
SAXBuilder sb = new SAXBuilder();
Document jDom = sb.build(new StringReader(otc));
// first step: associate products to otc documents
Map<Long,String> productDocumentNames = new HashMap<Long,String>();
Map<Long,String> productDocuments = new HashMap<Long,String>();
XPathExpression<Element> xpath = XPathFactory.instance().compile("//t", Filters.element());
List<Element> ts = xpath.evaluate(jDom);
for (Element t : ts) {
String documentName = t.getAttributeValue("d");
String productId = t.getChild("p").getChild("id").getValue();
// put it in, if there is a voucher for this product
if( documentName != null) {
productDocumentNames.put(Long.valueOf(productId), documentName);
} else {
System.out.println("No voucher associated with productId: " + productId);
}
}
List<Element> ds = jDom.getRootElement().getChildren("d");
for (Element d : ds) {
// for each document we find, we'll replace the document name with the content
String documentName = d.getAttributeValue("k");
Set<Long> productIds = productDocumentNames.keySet();
for(Long productId : productIds) {
if( productDocumentNames.get( productId ).equals( documentName ) ) {
findAndReplaceNestedDocs( jDom, d );
productDocuments.put( productId, new XMLOutputter( ).outputString( d.getContent() ) );
}
}
}
Set<Long> productIds = productDocuments.keySet();
for(Long productId : productIds) {
VoucherTemplate vt = VoucherTemplate.make(productId, "RETAILER_GROUP:*|CHANNEL:*|LOCALE:de-AT|INDUSTRY:5499", VoucherTemplate.TemplateSchema.OTC);
vt.setTemplate(productDocuments.get( productId ));
voucherTemplateDao.save(vt);
}
jDom.getRootElement().addContent( new Element("w") );
}
private void findAndReplaceNestedDocs(Document jDom, Element documentInOtcContent) {
// find the nested docs
List<Element> directives = documentInOtcContent.getChildren("w");
// and replace them
for(Element directive : directives) {
List<Element> docs = jDom.getRootElement().getChildren("d");
for (Element doc : docs) {
if (directive.getAttributeValue("d").equals(doc.getAttributeValue("k"))) {
List<Element> docContents = doc.getChildren();
List<Element> clones = new ArrayList<Element>();
for(Element docContent : docContents) {
Element docContentCopy = docContent.clone();
docContentCopy.detach();
clones.add(docContentCopy);
}
if (documentInOtcContent.indexOf(directive) != -1) {
documentInOtcContent.setContent(documentInOtcContent.indexOf(directive), clones);
}
}
}
break;
}
}
public String readFileAsString(String name, ApplicationContext ctx) {
String output = null;
// working code in here
return output;
}
}
}