如何从外部JAR加载Hibernate实体(How to load Hibernate entities from external JAR)
我试图从几个jar文件加载实体。 我设法做的是
配置hibernate
private void configure(File[] moduleFiles) { Configuration configuration = new Configuration() .setProperty("hibernate.connection.url", getConnectionString()) .setProperty("hibernate.connection.username", "user") .setProperty("hibernate.connection.password", "pass") .setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbc.JDBCDriver") .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect") .setProperty("hibernate.archive.autodetection", "class,hbm") .setProperty("exclude-unlisted-classes", "false") .setProperty("hibernate.hbm2ddl.auto", "update"); if (moduleFiles != null) { for (File f : moduleFiles) { configuration.addJar(f); } } ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); this.sessionFactory = configuration.buildSessionFactory(serviceRegistry); }
所以实体应该从moduleFiles数组加载。 在日志中,我可以看到:
2015-08-25 20:52:12 INFO Configuration:837 - HHH000235: Searching for mapping documents in jar: ProgramInfo.jar 2015-08-25 20:52:12 INFO Configuration:837 - HHH000235: Searching for mapping documents in jar: SampleModule.jar
外部jar中的实体
@Entity @Table(name = "PROGRAMINFO_DATA", schema = "PUBLIC", catalog = "PUBLIC") @NamedQueries({@NamedQuery(name = "PrograminfoDataEntity.findByWindowInfo", query = "FROM PrograminfoDataEntity WHERE PROCESSPATH = :pp AND WINDOWTITLE = :wt AND DAY = :d")}) public class PrograminfoDataEntity implements SVEntity { private long id; private Date day; private String processname; private String processpath; private String programname; private String windowtitle; // getters setters etc. }
外部jar中的persistence.xml(META-INF目录)
<persistence-unit name="ProgramInfoPersistenceUnit"> <class>com.antara.modules.programinfo.db.model.PrograminfoDataEntity</class> </persistence-unit>
查询以上实体用法
Session session = openSession(); Query q = session.getNamedQuery("PrograminfoDataEntity.findByWindowInfo"); q.setParameter("pp", windowInfo.getProcessPath()); q.setParameter("wt", windowInfo.getWindowTitle()); q.setDate("d", date); PrograminfoDataEntity result = (PrograminfoDataEntity) q.uniqueResult(); closeSession(session);
哪个例外:
org.hibernate.MappingException: Named query not known: PrograminfoDataEntity.findByWindowInfo at org.hibernate.internal.AbstractSessionImpl.getNamedQuery(AbstractSessionImpl.java:177) at org.hibernate.internal.SessionImpl.getNamedQuery(SessionImpl.java:1372) at com.antara.modules.programinfo.db.dao.PrograminfoDao.findByWindowInfo(PrograminfoDao.java:26) at com.antara.modules.programinfo.ProgramInfoImpl.run(ProgramInfoImpl.java:84)
问题是为什么hibernate没有从jar加载带注释的实体? 异常不仅由命名查询引发,而且还与实体的任何其他操作引发异常。 使用此实体前没有错误。 本地实体已正确加载。
编辑:
经过一些更改后,我设法通过Hibernate识别实体
DEBUG AnnotationBinder:601 - Binding entity from annotated class: com.antara.modules.programinfo.db.model.PrograminfoDataEntity DEBUG QueryBinder:93 - Binding named query: PrograminfoDataEntity.findByWindowInfo => FROM PrograminfoDataEntity ....
但是当我尝试使用该实体时,我仍然会遇到异常:
ERROR AssertionFailure:61 - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.ClassNotFoundException: com.antara.modules.programinfo.db.model.PrograminfoDataEntity ERROR Main:114 - PersistentClass name cannot be converted into a Class ... Caused by: java.lang.ClassNotFoundException: com.antara.modules.programinfo.db.model.PrograminfoDataEntity
更改是:将配置传递给jar中的每个“模块”并添加Annotated Class(模块我指的是SPI服务,启动时调用方法)
@Override public void configureDB(Configuration configuration) { configuration.addAnnotatedClass(PrograminfoDataEntity.class); }
I am trying to load entities from several jar files. What I managed to do is
configure hibernate
private void configure(File[] moduleFiles) { Configuration configuration = new Configuration() .setProperty("hibernate.connection.url", getConnectionString()) .setProperty("hibernate.connection.username", "user") .setProperty("hibernate.connection.password", "pass") .setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbc.JDBCDriver") .setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect") .setProperty("hibernate.archive.autodetection", "class,hbm") .setProperty("exclude-unlisted-classes", "false") .setProperty("hibernate.hbm2ddl.auto", "update"); if (moduleFiles != null) { for (File f : moduleFiles) { configuration.addJar(f); } } ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); this.sessionFactory = configuration.buildSessionFactory(serviceRegistry); }
so the entities should be loaded from moduleFiles array. In logs I can see:
2015-08-25 20:52:12 INFO Configuration:837 - HHH000235: Searching for mapping documents in jar: ProgramInfo.jar 2015-08-25 20:52:12 INFO Configuration:837 - HHH000235: Searching for mapping documents in jar: SampleModule.jar
The entity in external jar
@Entity @Table(name = "PROGRAMINFO_DATA", schema = "PUBLIC", catalog = "PUBLIC") @NamedQueries({@NamedQuery(name = "PrograminfoDataEntity.findByWindowInfo", query = "FROM PrograminfoDataEntity WHERE PROCESSPATH = :pp AND WINDOWTITLE = :wt AND DAY = :d")}) public class PrograminfoDataEntity implements SVEntity { private long id; private Date day; private String processname; private String processpath; private String programname; private String windowtitle; // getters setters etc. }
persistence.xml in external jar (META-INF directory)
<persistence-unit name="ProgramInfoPersistenceUnit"> <class>com.antara.modules.programinfo.db.model.PrograminfoDataEntity</class> </persistence-unit>
Query with above entity usage
Session session = openSession(); Query q = session.getNamedQuery("PrograminfoDataEntity.findByWindowInfo"); q.setParameter("pp", windowInfo.getProcessPath()); q.setParameter("wt", windowInfo.getWindowTitle()); q.setDate("d", date); PrograminfoDataEntity result = (PrograminfoDataEntity) q.uniqueResult(); closeSession(session);
which threw an exception:
org.hibernate.MappingException: Named query not known: PrograminfoDataEntity.findByWindowInfo at org.hibernate.internal.AbstractSessionImpl.getNamedQuery(AbstractSessionImpl.java:177) at org.hibernate.internal.SessionImpl.getNamedQuery(SessionImpl.java:1372) at com.antara.modules.programinfo.db.dao.PrograminfoDao.findByWindowInfo(PrograminfoDao.java:26) at com.antara.modules.programinfo.ProgramInfoImpl.run(ProgramInfoImpl.java:84)
The question is why hibernate didn't loaded the annotated entity from jar? The exception is thrown not only by named query, but any other operation with entity. There are no errors before usage of this entity. Local entities are loaded properly.
EDIT:
After some changes I managed to recognize entity by Hibernate
DEBUG AnnotationBinder:601 - Binding entity from annotated class: com.antara.modules.programinfo.db.model.PrograminfoDataEntity DEBUG QueryBinder:93 - Binding named query: PrograminfoDataEntity.findByWindowInfo => FROM PrograminfoDataEntity ....
But when I try to use the entity I still get exception:
ERROR AssertionFailure:61 - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.ClassNotFoundException: com.antara.modules.programinfo.db.model.PrograminfoDataEntity ERROR Main:114 - PersistentClass name cannot be converted into a Class ... Caused by: java.lang.ClassNotFoundException: com.antara.modules.programinfo.db.model.PrograminfoDataEntity
The change was: passing Configuration to each "module" that is inside jar and add Annotated Class (by module I mean SPI service with method invoked at startup)
@Override public void configureDB(Configuration configuration) { configuration.addAnnotatedClass(PrograminfoDataEntity.class); }
原文:https://stackoverflow.com/questions/32214935
最满意答案
根据您的预期输出,您似乎有兴趣选择距离大于 0.4的点对(这与您的问题描述不符)。 如果是这种情况,您可以尝试以下方法:
dist_pairs <- which(df1!=0 & df1 > 0.4, arr.ind=TRUE) dist_pairs[] <- sapply(dist_pairs, function(x) x <- letters[x]) > dist_pairs # row col #[1,] "c" "a" #[2,] "c" "b" #[3,] "a" "c" #[4,] "b" "c"
否则,如果您希望这些对低于阈值0.4,请将
>
符号更改为<
符号。数据
df1 <- structure(list(a = c(0, 0.2, 0.5), b = c(0.2, 0, 0.6), c = c(0.5, 0.6, 0)), .Names = c("a", "b", "c"), class = "data.frame", row.names = c(NA, -3L))
According to your expected output, you seem to be interested in selecting pairs of points with distances greater than 0.4 (which does not correspond to your problem description). If this is the case, you could try the following:
dist_pairs <- which(df1!=0 & df1 > 0.4, arr.ind=TRUE) dist_pairs[] <- sapply(dist_pairs, function(x) x <- letters[x]) > dist_pairs # row col #[1,] "c" "a" #[2,] "c" "b" #[3,] "a" "c" #[4,] "b" "c"
Else, if you want those pairs below the threshold of 0.4, change the
>
sign to a<
sign.data
df1 <- structure(list(a = c(0, 0.2, 0.5), b = c(0.2, 0, 0.6), c = c(0.5, 0.6, 0)), .Names = c("a", "b", "c"), class = "data.frame", row.names = c(NA, -3L))
相关问答
更多-
重新排序R中的行和列(Reordering rows and columns in R)[2022-10-14]
这是您的问题的潜在解决方案。 我试图根据你的问题重新创建一个小型的data.frame。 这里的关键是match函数以及R中的一些基本子集/过滤技术: ## Re-create your example: V <- data.frame( A = c(1 , 0.3, 0.1 , 0.4), B = c(0.2, 1 , 0.4 , 0.3), C = c(0.1, 0 , 1 , 0.9), D = c(0.3, 0.3, 0.1 , 1) ) #matrix() also ok ... -
另外一个选择: df[rowSums(sapply(df[-4], '%in%', c('D', 'E', 'G'))) > 0,] 结果: Tour Order Machine Company 1 A D D B 3 A E B A 5 A G G C 使用dplyr你应该添加rowwise() : df %>% rowwise() %>% filter(any(c(Tour ...
-
我们可以用%in%来做到这一点 df1[!seq_len(nrow(df1)) %in% sapply(df1, which.max),] # A B C #4 2 1 1 如果每行都有最大值的关系,那么就做 df1[!Reduce(`|`, lapply(df1, function(x) x== max(x))),] We can do this with %in% df1[!seq_len(nrow(df1)) %in% sapply(df1, which.max),] # A B C #4 2 ...
-
一个班轮: merge(dat, data.frame(table(dat[1:3]))[-4],all.y=TRUE) # A B C D #1 1 1 1 200 #2 1 1 2 50 #3 1 1 3 15 #4 1 1 4 NA #... 或者可能不那么复杂: out <- data.frame(xtabs(D ~ ., data=dat)) out[do.call(order,out[1:3]),] # A B C Freq #1 1 1 1 200 #7 ...
-
尝试这样的事情 我编辑你的函数来处理单个文件,并在用NA滤除行之后返回行数 count_nobs <- function(fi) { require(dplyr) dat <- read.csv(fi) dat[complete.cases(dat), ] %>% count() } 使用purrr:map_dfr调用函数,它遍历files_list并对结果进行files_list library(tidyverse) files_list <- list.files(direct ...
-
这将找到全局欺骗,但它会按列搜索。 所以(3,1)仍然是FALSE,因为它是数据帧中的第一个值16 。 m <- matrix(duplicated(unlist(df)), ncol=ncol(df)) # [,1] [,2] [,3] #[1,] FALSE FALSE FALSE #[2,] FALSE TRUE FALSE #[3,] FALSE FALSE FALSE #[4,] FALSE FALSE FALSE #[5,] FALSE FALSE FALSE #[6,] FAL ...
-
首先要做的是你的字符串是字符而不是因素: A = c("AA","AA","AA","AA","AA") B = c("CC","GG","CC","CG","GG") C = c("TT","AA","AA","AT","TT") D = c("GG","GG","GG","GG","GG") E = c("TT","TT","NA","TT","TT") mydata = data.frame(A, B, C, D, E,stringsAsFactors = F) 然后,在第一步,您可以执行以下操作 ...
-
我们可以在感兴趣的列上对数据集的子集应用duplicated ,以查找所有重复的行并使用它来对行进行子集化 df1[duplicated(df1[c('c1','c3')])|duplicated(df1[c('c1','c3')], fromLast=TRUE),] # c1 c2 c3 #1 2 3 8 #3 2 9 8 We can apply duplicated on the subset of dataset with the columns of interest to fin ...
-
根据您的预期输出,您似乎有兴趣选择距离大于 0.4的点对(这与您的问题描述不符)。 如果是这种情况,您可以尝试以下方法: dist_pairs <- which(df1!=0 & df1 > 0.4, arr.ind=TRUE) dist_pairs[] <- sapply(dist_pairs, function(x) x <- letters[x]) > dist_pairs # row col #[1,] "c" "a" #[2,] "c" "b" #[3,] "a" "c" #[4,] "b ...
-
这是一个非常简单的衬里,可以得到你想要的。 没有循环或需要申请。 df[is.na(df) & df$Type=='A'] <- 0 Here is a very simple one liner that gets exactly what you want. No loops or apply needed. df[is.na(df) & df$Type=='A'] <- 0