GithubHelp home page GithubHelp logo

jmix-data's People

Contributors

andreysubbotin avatar artemglinov avatar bulgakovea avatar desire456 avatar dtaimanov avatar flaurite avatar gorbunkov avatar knstvk avatar nikitashchienko avatar plakhov avatar soraksh avatar ted-the-coder avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jmix-data's Issues

Data from nested instance name is not displayed

1.0.0-SNAPSHOT

  1. Open project detachh.zip
  2. Run the app
  3. Open Schedule browser
  4. Create one

ER: instance names should be correct
AR: the Lesson field is detached (Teacher part)
Editor:
image
Browser:
image

Lesson get instance name method:

    @InstanceName
    @DependsOnProperties({"teacher", "subject"})
    public String getInstanceName() {
        return String.format("%s %s", teacher, subject);
    }

Teacher get instance name method:

    @InstanceName
    @DependsOnProperties({"firstName", "lastName"})
    public String getInstanceName() {
        return String.format("%s %s", firstName, lastName);
    }

IllegalStateException occurs when putting new entity with String id into HashMap

Jmix version: 1.0.0-SNAPSHOT

  1. Create entity with String ID
public class StringEntity {
    @Column(name = "ID", nullable = false)
    @Id
    private String id;

    @JmixGeneratedValue
    @Column(name = "UUID")
    private UUID uuid;
  1. Create standard browser and editor screens for that entity
  2. Try to create new entity instance using these screens

AR:

java.lang.IllegalStateException: Generated ID is null in com.company.jmixfronttest.entity.StringEntity-null [new]
	at io.jmix.core.EntityEntry.getGeneratedId(EntityEntry.java:41)
	at io.jmix.core.entity.BaseEntityEntry.hashCode(BaseEntityEntry.java:61)
	at io.jmix.core.impl.EntityInternals.hashCode(EntityInternals.java:78)
	at com.company.jmixfronttest.entity.StringEntity.hashCode(StringEntity.java)
	at java.base/java.util.HashMap.hash(HashMap.java:339)
	at java.base/java.util.HashMap.put(HashMap.java:607)
	at io.jmix.ui.model.impl.DataContextImpl.internalMerge(DataContextImpl.java:221)
	at io.jmix.ui.model.impl.DataContextImpl.merge(DataContextImpl.java:156)
	at io.jmix.ui.model.impl.DataContextImpl.merge(DataContextImpl.java:165)
	at io.jmix.ui.screen.StandardEditor.setupEntityToEdit(StandardEditor.java:212)
	at io.jmix.ui.screen.StandardEditor.beforeShow(StandardEditor.java:153)
	at io.jmix.core.common.event.EventHub.publish(EventHub.java:170)
	at io.jmix.ui.screen.Screen.fireEvent(Screen.java:124)
	at io.jmix.ui.screen.UiControllerUtils.fireEvent(UiControllerUtils.java:58)
	at io.jmix.ui.sys.ScreensImpl.fireScreenBeforeShowEvent(ScreensImpl.java:1356)
	at io.jmix.ui.sys.ScreensImpl.show(ScreensImpl.java:353)
	at io.jmix.ui.screen.Screen.show(Screen.java:306)
	at io.jmix.ui.action.list.CreateAction.execute(CreateAction.java:358)
	at io.jmix.ui.action.list.CreateAction.actionPerform(CreateAction.java:300)
...

Consider changing constant names for dbmsType

In CUBA and Jmix PostgreSQL has constant name "postgres", HSQLDB - "hsql".

Spring Data and Liquibase have its own enumerations for dbms type with other constant names.

  1. Spring Data - property spring.jpa.database

Target database to operate on, auto-detected by default. Can be alternatively set using the "databasePlatform" property.

https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html

List of constants - org.springframework.orm.jpa.vendor.Database ("postresql", "hsql", "sql_server")

  1. Liquibase - https://www.liquibase.org/get-started/databases

Maybe we should use switch to constant names provided by Spring Data or Liquibase, for consistency?

Cannot fetch reference attribute without explicit fetch plan in Many-To-Many case

As presented Jmix should provide extracting references from entity even if there is no any fetch plan exactly specified, but in my case when using Many-To-Many relation I've got
IllegalStateException: Cannot get unfetched attribute [users] from detached object com.company.fetchplantest.entity.UserGroup-9314af20-5d49-69be-2be2-07a85999647f [detached].

Definition of entity

@JmixEntity
@Table(name = "TEST_USER_GROUP")
@Entity(name = "test_UserGroup")
public class UserGroup {
    @JoinTable(name = "FETCHPLANTEST_USER_GROUP_USER_LINK",
            joinColumns = @JoinColumn(name = "USER_GROUP_ID"),
            inverseJoinColumns = @JoinColumn(name = "USER_ID"))
    @ManyToMany
    private List<User> users;

user-group-edit descriptor

    <data>
        <instance id="userGroupDc"
                  class="com.company.fetchplantest.entity.UserGroup">
            <fetchPlan extends="_local"/>
            <loader/>
            <collection id="usersDc" property="users"/>
        </instance>
    </data>

Please take a look, simple test project in attach
fetchplantest.zip

Cross-datastore references are not implemented?

Sample project: attached
ikna.zip

SQL dumps of databases: attached
dumps.zip

Create locally two empty Postgres databases: ikna and ikna_stats. Restore data from DB dumps.
Launch application.

Cross-datastore references are defined the following way:

    @NotNull
    @SystemLevel
    @Column(name = "USER_ID", nullable = false)
    private UUID userId;

    @NotNull
    @SystemLevel
    @Column(name = "DECK_ID", nullable = false)
    private Long deckId;

    @Transient
    @ModelProperty(mandatory = true)
    @DependsOnProperties("deckId")
    private Deck deck;

    @Transient
    @ModelProperty(mandatory = true)
    @DependsOnProperties("userId")
    private User user;

Open Deck Study States browser through menu.

If you insert manually data to ikna_stats.IKNA_DECK_STUDY_STATE table - then cross-datastore links in the browser will not be loaded

  1. Try to create new DeckStudyState. Select user and deck in the editor.
    Try to save entity - it's not saved, because userId and deckId are not filled.
PSQLException: ERROR: null value in column "user_id" violates not-null constraint
  Detail: Failing row contains (7, null, null).

Support for relative date and time moments in JPQL queries

At least the following:

  • First and last days of the current year/month/week
  • Start and end of the current day (00:00:00 и 23:59:59)
  • Start of the last and next days (00:00:00)
  • Start and end of the current hour (00:00 и 59:59)
  • Start and end of the current minute

Task description in the documentation: https://youtrack.haulmont.com/articles/PLAT-A-128/Relative-date-and-time-moments-in-JPQL-queries

Definition

The approach is adding a new constant (as exist JPQL constants - CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP):

FIRST_DAY_OF_CURRENT_YEAR
LAST_DAY_OF_CURRENT_YEAR
FIRST_DAY_OF_CURRENT_MONTH
LAST_DAY_OF_CURRENT_MONTH
FIRST_DAY_OF_CURRENT_WEEK
LAST_DAY_OF_CURRENT_WEEK
START_OF_CURRENT_DAY
END_OF_CURRENT_DAY
START_OF_YESTERDAY
START_OF_TOMORROW
START_OF_CURRENT_HOUR
END_OF_CURRENT_HOUR
START_OF_CURRENT_MINUTE
END_OF_CURRENT_MINUTE

User's queries can use the constants. Before executing queries constants will be replaced to the current date&time moment.

Example:
User's query
SELECT * FROM USER u WHERE u.createdDate > FIRST_DAY_OF_YEAR
after replacing
SELECT * FROM USER u WHERE u.createdDate > '2021-01-01'

Progress

2021-04-14: 80%

Parts of task:

  • Define a view (article in the knowledge base)
  • Create a mockup for adding into filters (article in the knowledge base)
  • Implement view in code
  • Write tests
  • Code review
  • QA

Unexpected error occurs when creating an entity generated from Oracle database

bomVersion = '1.0.0-SNAPSHOT'

see also the similar problem for MSSQL in #54

  1. Connect to Oracle server using a third-party program and execute sql script Sample-Oracle.sql.txt
  2. Create data store and connect it to this database
  3. Click Generate model, refresh list
  4. Select All tables -> Finish
  5. Add missed attributes to screens if needed
  6. Run the app
  7. Open Individual browser
  8. Create item

AR: Unexpected error occurs when trying to save

OracleDatabaseException: ORA-00001: нарушено ограничение уникальности (IRA_TEST.SYS_C003581863)
Error : 1, Position : 0, Sql = INSERT INTO INDIVIDUAL ("CUST_ID", "BIRTH_DATE", "FIRST_NAME", "LAST_NAME") VALUES (:1 , :2 , :3 , :4 ), OriginalSql = INSERT INTO INDIVIDUAL ("CUST_ID", "BIRTH_DATE", "FIRST_NAME", "LAST_NAME") VALUES (?, ?, ?, ?), Error Msg = ORA-00001: нарушено ограничение уникальности (IRA_TEST.SYS_C003581863)

The id defined as

    @JmixGeneratedValue
    @Column(name = "\"CUST_ID\"", nullable = false)
    @Id
    private Integer id;

ER: correct saving

ClassCastException into LazyLoadingHelper

Steps for reproduce:

  1. Create two entity related One-to-One composition (e.g. Planet -> Atmosphere).
  2. Both ID have type UUID in database Postgresql 9.6
  3. ID in entity also have UUID type.
  4. Also create browse screens for entities
  5. Create related data
  6. Open owner entity browse screen.

AR: Showing window with ClassCastException
ER: Showing browse screen

Click to expand
java.lang.ClassCastException: java.util.UUID cannot be cast to java.lang.String
	at io.jmix.data.impl.lazyloading.LazyLoadingHelper.replaceValueHoldersInternal(LazyLoadingHelper.java:134)
	at io.jmix.data.impl.lazyloading.LazyLoadingHelper.replaceValueHolders(LazyLoadingHelper.java:89)
	at io.jmix.data.impl.lazyloading.LazyLoadingHelper.onLoad(LazyLoadingHelper.java:68)
	at io.jmix.data.impl.OrmDataStore.fireLoadListeners(OrmDataStore.java:1125)
	at io.jmix.data.impl.OrmDataStore.loadList(OrmDataStore.java:316)
	at io.jmix.core.impl.DataManagerImpl.loadList(DataManagerImpl.java:86)
	at io.jmix.ui.model.impl.CollectionLoaderImpl.load(CollectionLoaderImpl.java:90)
	at io.jmix.ui.component.dataloadcoordinator.OnFrameOwnerEventLoadTrigger.load(OnFrameOwnerEventLoadTrigger.java:48)
	at io.jmix.ui.component.dataloadcoordinator.OnFrameOwnerEventLoadTrigger.lambda$new$0(OnFrameOwnerEventLoadTrigger.java:39)
	at io.jmix.core.common.event.EventHub.publish(EventHub.java:170)
	at io.jmix.ui.screen.Screen.fireEvent(Screen.java:124)
	at io.jmix.ui.screen.UiControllerUtils.fireEvent(UiControllerUtils.java:57)
	at io.jmix.ui.sys.WebScreens.show(WebScreens.java:373)
	at io.jmix.ui.sys.WebScreens.showFromNavigation(WebScreens.java:479)
	at io.jmix.ui.menu.MenuItemCommands$ScreenCommand.run(MenuItemCommands.java:292)
	at io.jmix.ui.menu.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:273)
	at io.jmix.ui.menu.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:258)
	at io.jmix.ui.component.mainwindow.impl.WebSideMenu$MenuItemImpl.menuSelected(WebSideMenu.java:580)
	at io.jmix.ui.widget.JmixSideMenu$1.menuItemTriggered(JmixSideMenu.java:91)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:431)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:396)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:260)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:82)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1578)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:425)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:158)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:152)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

Liquibase update fails on Windows with the Not a valid resource entry error

  1. Create a new jmix project on a Windows machine (on mac the issue is not reproduced)
  2. Add a dependency to the reports starter: implementation 'io.jmix.reports:jmix-reports-starter
  3. Start the application from the terminal: gradlew bootRun

AR: errors in log file:

2021-02-01 11:33:58.900  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.data/jmix-data/0.3.0-SNAPS
HOT/c8d1ef571d97b2be827068d8fff0034d1d76b240/jmix-data-0.3.0-SNAPSHOT.jar!/io/jmix/data/liquibase/changelog/
2021-02-01 11:33:58.900  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.data/jmix-data/0.3.0-SNAPS
HOT/c8d1ef571d97b2be827068d8fff0034d1d76b240/jmix-data-0.3.0-SNAPSHOT.jar!/io/jmix/data/liquibase/changelog/001-data.xml
2021-02-01 11:33:58.915  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.reports/jmix-reports/0.3.0
-SNAPSHOT/18123c1768bc0dfc31013852aa8a3968cab7b0d9/jmix-reports-0.3.0-SNAPSHOT.jar!/io/jmix/reports/liquibase/changelog/
2021-02-01 11:33:58.915  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.reports/jmix-reports/0.3.0
-SNAPSHOT/18123c1768bc0dfc31013852aa8a3968cab7b0d9/jmix-reports-0.3.0-SNAPSHOT.jar!/io/jmix/reports/liquibase/changelog/001-reports.xml
2021-02-01 11:33:58.931  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.security/jmix-security-dat
a/0.3.0-SNAPSHOT/20d5778fef8dc59d12375d0ef04210967fbafb43/jmix-security-data-0.3.0-SNAPSHOT.jar!/io/jmix/securitydata/liquibase/changelog/
2021-02-01 11:33:58.931  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.security/jmix-security-dat
a/0.3.0-SNAPSHOT/20d5778fef8dc59d12375d0ef04210967fbafb43/jmix-security-data-0.3.0-SNAPSHOT.jar!/io/jmix/securitydata/liquibase/changelog/001-security-data.xml
2021-02-01 11:33:58.947  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.ui/jmix-ui-data/0.3.0-SNAP
SHOT/5f06a82e4b97e16f39834ca27454268d87d419b1/jmix-ui-data-0.3.0-SNAPSHOT.jar!/io/jmix/uidata/liquibase/changelog/
2021-02-01 11:33:58.947  WARN 7080 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/C:/Users/mgorb/.gradle/caches/modules-2/files-2.1/io.jmix.ui/jmix-ui-data/0.3.0-SNAP
SHOT/5f06a82e4b97e16f39834ca27454268d87d419b1/jmix-ui-data-0.3.0-SNAPSHOT.jar!/io/jmix/uidata/liquibase/changelog/001-ui-data.xml

There is an issue in the liquibase issue tracker: liquibase/liquibase#1029
The issue says that the problem may be in the includeAll tag and that the problem may be solved in liquibase 4+. It seems that the solution may be to increase the liquibase version in Jmix.

Support initial loading context for lazy loading

Access constraints, dynamic attributes, soft deletion flag are specified when loading entity using DataManager.
After loading the entity when performing lazy loading for the entity attributes you must use the initial loading context parameters (access constraints, dynamic attributes, soft deletion)

In addition:

  • Soft deletion should work only *toMany references
  • JPQL RLS should never apply, only in-memory constraints.

Do not enhance entities from compileOnly dependency

Problem

Jmix gradle plugin processes entities from compileOnly dependencies. This entities can be related to entities from other modules that are absent in classpath, which leads to build failure.

Steps:

  1. Add compileOnly 'io.jmix.security:jmix-security-ui' dependency to email.gradle in jmix-email module
  2. Run gradle build
    ER: BUILD SUCCESSFULL
    AR: BUILD FAILED
javassist.NotFoundException: io.jmix.securitydata.entity.RoleEntity
        at javassist.ClassPool.get(ClassPool.java:422)
        at io.jmix.gradle.DescriptorGenerationUtils.findExtendedClasses(DescriptorGenerationUtils.java:129)
        at io.jmix.gradle.DescriptorGenerationUtils.constructOrmXml(DescriptorGenerationUtils.java:109)
        at io.jmix.gradle.DescriptorGenerationUtils$constructOrmXml$0.call(Unknown Source)
        at io.jmix.gradle.EnhancingAction.constructDescriptors(EnhancingAction.groovy:183)
        at io.jmix.gradle.EnhancingAction.execute(EnhancingAction.groovy:52)
        at io.jmix.gradle.EnhancingAction.execute(EnhancingAction.groovy)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:731)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:704)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:555)
        ... 90 more

Solution:

Exclude entities from modules that are absent in runtimeClasspath.

Application fails to start if additional datastore has no entities

Steps

  1. Create new Jmix-project
  2. Create additional datastore
  3. Run project
    ER: project starts without problems
    AR: java.lang.IllegalArgumentException: Cannot parse persistence unit from class path resource [com/company/untitled1/test1-persistence.xml]

Cause:

Jmix gradle plugin doesn't know about additional datastores and cannot create appropriate *-persistence.xml if there is no entity related to datastore.

Proposed solution:

Ignore absent additional *-persistence.xml and setup persistence unit settings from code instead (if need)

Lazy loading of associations doesn't trigger in screen with non-read-only data context

Project: attached
llo2.zip

deck-browse.xml:

  • fetch plan not set
  • I have removed "readonly = true" from "data" tag

scenario

  • launch app
  • create Language
  • create Deck, fill required fields
  • reopen Deck browser

Associations are not lazy-loaded, plain old unfetched attribute error:

Click to expand
java.lang.IllegalStateException: Cannot get unfetched attribute [language] from detached object com.company.llo2.entity.Deck-1 [detached].
	at org.eclipse.persistence.internal.queries.EntityFetchGroup.onUnfetchedAttribute(EntityFetchGroup.java:100)
	at io.jmix.data.impl.JmixEntityFetchGroup.onUnfetchedAttribute(JmixEntityFetchGroup.java:67)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.processUnfetchedAttribute(EntityManagerImpl.java:3027)
	at com.company.llo2.entity.Deck._persistence_checkFetched(Deck.java)
	at com.company.llo2.entity.Deck._persistence_get_language(Deck.java)
	at com.company.llo2.entity.Deck.getLanguage(Deck.java:112)
	at io.jmix.core.entity.BaseEntityEntry.getAttributeValue(BaseEntityEntry.java:73)
	at io.jmix.core.entity.EntityValues.getValue(EntityValues.java:90)
	at io.jmix.core.entity.EntityValues.getValueEx(EntityValues.java:121)
	at io.jmix.ui.component.data.table.ContainerTableItems.getItemValue(ContainerTableItems.java:116)
	at io.jmix.ui.component.table.TableItemWrapper.getPropertyValue(TableItemWrapper.java:81)
	at io.jmix.ui.component.table.TableItemPropertyWrapper.getValue(TableItemPropertyWrapper.java:37)
	at io.jmix.ui.component.impl.AbstractTable.formatCellValue(AbstractTable.java:1246)
	at io.jmix.ui.widget.JmixTable.formatPropertyValue(JmixTable.java:354)
	at io.jmix.ui.widget.JmixTable.getPropertyValue(JmixTable.java:269)
	at com.vaadin.v7.ui.Table.parseItemIdToCells(Table.java:2371)
	at com.vaadin.v7.ui.Table.getVisibleCellsNoCache(Table.java:2219)
	at com.vaadin.v7.ui.Table.refreshRenderedCells(Table.java:1762)
	at io.jmix.ui.widget.JmixGroupTable.refreshRenderedCells(JmixGroupTable.java:753)
	at com.vaadin.v7.ui.Table.attach(Table.java:4276)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)

Lazy loading doens't work in master-detail editing screen

Project attached:
masdet.zip

In writer-edit.xml I forgot to include "Book.genre" property which is displayed in the table:

        <instance id="writerDc"
                  class="com.company.masdet.entity.Writer">
            <fetchPlan extends="_local">
                <property name="books" fetchPlan="_instance_name">
                    <property name="name"/>
                    <!--<property name="genre"/>-->
                </property>
            </fetchPlan>
            <loader/>
            <collection id="booksDc" property="books"/>
        </instance>
  • launch app
  • create one Book
  • create one Writer, add book to writer
  • reopen Writer for editing

exception occurs:
image

java.lang.IllegalStateException: Cannot get unfetched attribute [genre] from detached object com.company.masdet.entity.Book-4b0dbdf0-1d9c-c152-e5d6-ee55ba7aa63f [detached].
	at org.eclipse.persistence.internal.queries.EntityFetchGroup.onUnfetchedAttribute(EntityFetchGroup.java:100)
	at io.jmix.data.impl.JmixEntityFetchGroup.onUnfetchedAttribute(JmixEntityFetchGroup.java:67)
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.processUnfetchedAttribute(EntityManagerImpl.java:3027)
	at com.company.masdet.entity.Book._persistence_checkFetched(Book.java)
	at com.company.masdet.entity.Book._persistence_get_genre(Book.java)
	at com.company.masdet.entity.Book.getGenre(Book.java:32)
	at io.jmix.core.entity.BaseEntityEntry.getAttributeValue(BaseEntityEntry.java:73)
	at io.jmix.core.entity.EntityValues.getValue(EntityValues.java:90)
	at io.jmix.core.entity.EntityValues.getValueEx(EntityValues.java:121)
	at io.jmix.ui.component.data.table.ContainerTableItems.getItemValue(ContainerTableItems.java:116)
	at io.jmix.ui.component.table.TableItemWrapper.getPropertyValue(TableItemWrapper.java:81)
	at io.jmix.ui.component.table.TableItemPropertyWrapper.getValue(TableItemPropertyWrapper.java:37)
	at io.jmix.ui.component.impl.AbstractTable.formatCellValue(AbstractTable.java:1225)
	at io.jmix.ui.widget.JmixTable.formatPropertyValue(JmixTable.java:354)
	at io.jmix.ui.widget.JmixTable.getPropertyValue(JmixTable.java:269)
	at com.vaadin.v7.ui.Table.parseItemIdToCells(Table.java:2371)
	at com.vaadin.v7.ui.Table.getVisibleCellsNoCache(Table.java:2219)
	at com.vaadin.v7.ui.Table.refreshRenderedCells(Table.java:1762)
	at com.vaadin.v7.ui.Table.attach(Table.java:4276)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643)
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670)
	at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:571)
	at com.vaadin.ui.AbstractComponentContainer.addComponent(AbstractComponentContainer.java:178)
	at com.vaadin.ui.CssLayout.addComponent(CssLayout.java:121)
	at io.jmix.ui.sys.ScreensImpl.showThisTabWindow(ScreensImpl.java:1195)
	at io.jmix.ui.sys.ScreensImpl.show(ScreensImpl.java:374)
	at io.jmix.ui.screen.Screen.show(Screen.java:306)
	at io.jmix.ui.action.list.EditAction.execute(EditAction.java:363)
	at io.jmix.ui.action.list.EditAction.actionPerform(EditAction.java:310)
	at io.jmix.ui.component.impl.AbstractTable.handleClickAction(AbstractTable.java:1358)
	at io.jmix.ui.component.impl.AbstractTable.lambda$initComponent$db766529$1(AbstractTable.java:1110)
	at jdk.internal.reflect.GeneratedMethodAccessor107.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)

Lazy loading refactoring

Extract base classes. Remove duplicate code for value holder access, duplicates resolving, extracting id from the value holder

Entities from other modules in composite project again aren't accessible

The problem appeared previously is seen again.

  1. Open "jmix-all" workspace, launch io.jmix.sampler.SamplerApplication
    When you try to open http://localhost:8080/sampler/
    it fails with exception about unknown entities from other module:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'io.jmix.ui.component.impl.AppWorkAreaImpl': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Problem compiling [select s from ui_Setting s where s.userLogin = ?1 and s.name =?2]. 
[14, 24] The abstract schema type 'ui_Setting' is unknown.
[33, 44] The state field path 's.userLogin' cannot be resolved to a valid type.
[54, 60] The state field path 's.name' cannot be resolved to a valid type.
  1. Open composite project sample https://git.haulmont.com/budarov/drugstore-jmix-sample
    Try to rebuild the project.
    Exception happens during enhancing:
Exception [EclipseLink-40007] (Eclipse Persistence Services - 2.7.7.2-jmix): org.eclipse.persistence.exceptions.StaticWeaveException
Exception Description: An exception was thrown while weaving: [Ljava.lang.String;@59662a0b
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.7.2-jmix): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [main] failed.
Internal Exception: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.7.7.2-jmix): org.eclipse.persistence.exceptions.ValidationException
Exception Description: [class com.sample.drugstore.entity.FavouriteMedicine] uses a non-entity [class com.sample.contacts.entity.Contact] as target entity in the relationship attribute [field contact].

Enhancer working on module "drugstore" (FavouriteMedicine) doesn't take into account entity from module "contacts" (Contact).

Create orm.xml at build time

Second part of #5
Move io.jmix.data.impl.MappingFileCreator logic into io.jmix.gradle.EnhancingAction

Tasks:
  • Generate the same orm.xml at build time
  • Disable runtime orm.xml generation and fix possible problems, look for exceptions in logs
  • Refactor (remove) io.jmix.data.impl.PersistenceConfigProcessor.java
  • Recheck and improve existitng tests: cover all common cases, cover specific cases when it is reasonable

Important changes:

Property jmix.disableOrmXmlGeneration has been removed.

Error creating UUID from database value exception while login to the application

Description

  • database: mysql-5 (probably the same with mariaDb)
  • demo project: dbmysql.zip

Steps to reproduce

  1. Download demo project;
  2. Launch the app and try to login
Caused by: org.springframework.security.authentication.InternalAuthenticationServiceException: java.lang.RuntimeException: Error creating UUID from database value '60885987-1b61-4247-94c7-dff348347f93'
	at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:108) ~[spring-security-core-5.4.2.jar:5.4.2]
	at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:133) ~[spring-security-core-5.4.2.jar:5.4.2]
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.4.2.jar:5.4.2]
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201) ~[spring-security-core-5.4.2.jar:5.4.2]
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:510) ~[spring-security-config-5.4.2.jar:5.4.2]
	at io.jmix.securityui.authentication.LoginScreenAuthenticationSupport.authenticate(LoginScreenAuthenticationSupport.java:114) ~[jmix-security-ui-0.3.0-SNAPSHOT.jar:na]
	at com.company.dbmysql.screen.login.LoginScreen.login(LoginScreen.java:85) ~[main/:na]
	at com.company.dbmysql.screen.login.LoginScreen.onSubmitActionPerformed(LoginScreen.java:70) ~[main/:na]
	at io.jmix.core.common.event.EventHub.publish(EventHub.java:170) ~[jmix-core-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.ui.action.BaseAction.actionPerform(BaseAction.java:220) ~[jmix-ui-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.ui.component.impl.ButtonImpl.buttonClicked(ButtonImpl.java:75) ~[jmix-ui-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.ui.widget.JmixButton.fireClick(JmixButton.java:77) ~[jmix-ui-0.3.0-SNAPSHOT.jar:na]
	at com.vaadin.ui.Button$1.click(Button.java:57) ~[vaadin-server-8.9.2-6-jmix.jar:8.9.2-6-jmix]
	... 88 common frames omitted
Caused by: javax.persistence.PersistenceException: java.lang.RuntimeException: Error creating UUID from database value '60885987-1b61-4247-94c7-dff348347f93'
	at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:493) ~[org.eclipse.persistence.jpa-2.7.7-2-jmix.jar:na]
	at io.jmix.eclipselink.impl.JmixEclipseLinkQuery.getResultFromCache(JmixEclipseLinkQuery.java:767) ~[jmix-eclipselink-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.eclipselink.impl.JmixEclipseLinkQuery.getResultList(JmixEclipseLinkQuery.java:131) ~[jmix-eclipselink-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.eclipselink.impl.JpaDataStore.executeQuery(JpaDataStore.java:466) ~[jmix-eclipselink-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.eclipselink.impl.JpaDataStore.loadAll(JpaDataStore.java:160) ~[jmix-eclipselink-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.core.datastore.AbstractDataStore.loadList(AbstractDataStore.java:127) ~[jmix-core-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.core.impl.DataManagerImpl.loadList(DataManagerImpl.java:91) ~[jmix-core-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.core.FluentLoader$ByQuery.list(FluentLoader.java:487) ~[jmix-core-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.securitydata.user.AbstractDatabaseUserRepository.loadUserByUsername(AbstractDatabaseUserRepository.java:141) ~[jmix-security-data-0.3.0-SNAPSHOT.jar:na]
	at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:93) ~[spring-security-core-5.4.2.jar:5.4.2]
	... 100 common frames omitted
Caused by: java.lang.RuntimeException: Error creating UUID from database value '60885987-1b61-4247-94c7-dff348347f93'
	at io.jmix.eclipselink.impl.UuidConverter.convertDataValueToObjectValue(UuidConverter.java:71) ~[jmix-eclipselink-0.3.0-SNAPSHOT.jar:na]
	at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getObjectValue(AbstractDirectMapping.java:625) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1241) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.buildCloneFromRow(AbstractDirectMapping.java:227) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:2007) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:2268) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:858) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:745) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:699) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:858) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:987) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:598) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1229) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:911) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1188) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:485) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1276) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:3022) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1895) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1877) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1842) ~[org.eclipse.persistence.core-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:262) ~[org.eclipse.persistence.jpa-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:482) ~[org.eclipse.persistence.jpa-2.7.7-2-jmix.jar:na]
	... 109 common frames omitted
Caused by: java.lang.IllegalArgumentException: 60885987--1b6-1-42-47-9-4c7-dff348347f93
	at io.jmix.core.UuidProvider.fromString(UuidProvider.java:58) ~[jmix-core-0.3.0-SNAPSHOT.jar:na]
	at io.jmix.eclipselink.impl.UuidConverter.convertDataValueToObjectValue(UuidConverter.java:63) ~[jmix-eclipselink-0.3.0-SNAPSHOT.jar:na]
	... 131 common frames omitted

Weird ReferenceToEntity entity name

io.jmix.data.entity.ReferenceToEntity

@Embeddable
@ModelObject(name = "test$ReferenceToEntity")
@SystemLevel
public class ReferenceToEntity implements JmixEntity {

This entity is in production source code, why is it "test$" ?

ReferenceId considered as loaded for lazy-properties in full views

Reproduction

see spec.haulmont.cuba.core.persistence_tools.GetReferenceIdTest#"get existing not loaded reference id" (after jmix-projects/jmix-cuba#27 finish)

Cause

org.eclipse.persistence.descriptors.FetchGroupManager#getEntityFetchGroup(...) considers FetchGroup with all properties as full even if some properties are lazy. It sets fetch group to null and leads to wrong result in io.jmix.data.PersistenceTools#getReferenceId(...)

Possible soultion

Unfortunately, at the moment of PersistenceTools#getReferenceId(...) invocation, there are no differences between:

  • no fetchGroup,
  • full fetchGroup with no lazy properties,
  • full fetchGroup with some lazy properties.

so, we have to modify FetchGroupManager#getEntityFetchGroup(...) mechanism and make it not consider fetchGroup build by fetch plan with lazy properties as full or pas some hint for PersistenceTools#getReferencId

Lazy loading of unfetched association fails with exception

Project: attached
lazylo.zip

In the car-browse.xml -- collection container doesn't have necessary fields in fetchPlan.

  • launch app
  • create one VehicleColor
  • create one Model
  • create one Car with all properties set
  • reopen Car browser
Exception occurs:
2020-12-02 16:38:30.803 ERROR 52504 --- [nio-8080-exec-5] i.j.u.exception.DefaultExceptionHandler  : Unhandled exception

com.vaadin.server.ServerRpcManager$RpcInvocationException: Unable to invoke method menuItemTriggered in io.jmix.ui.widget.client.verticalmenu.JmixSideMenuServerRpc
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:157) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
...
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_275]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_275]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.39.jar:9.0.39]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_275]
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_275]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_275]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_275]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_275]
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	... 83 common frames omitted
Caused by: com.vaadin.v7.ui.Table$CacheUpdateException: Error during Table cache update. Additional causes not shown.
	at com.vaadin.v7.ui.Table.maybeThrowCacheUpdateExceptions(Table.java:1780) ~[vaadin-compatibility-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.v7.ui.Table.refreshRenderedCells(Table.java:1769) ~[vaadin-compatibility-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at io.jmix.ui.widget.JmixGroupTable.refreshRenderedCells(JmixGroupTable.java:753) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at com.vaadin.v7.ui.Table.attach(Table.java:4276) ~[vaadin-compatibility-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:643) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:670) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:571) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.AbstractComponentContainer.addComponent(AbstractComponentContainer.java:178) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.TabSheet.addTab(TabSheet.java:397) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.TabSheet.addTab(TabSheet.java:433) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.ui.TabSheet.addTab(TabSheet.java:414) ~[vaadin-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at io.jmix.ui.widget.JmixMainTabSheet$TabSheetBehaviourImpl.addTab(JmixMainTabSheet.java:468) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.sys.ScreensImpl.createNewTabLayout(ScreensImpl.java:1117) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.sys.ScreensImpl.showNewTabWindow(ScreensImpl.java:1070) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.sys.ScreensImpl.show(ScreensImpl.java:379) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.sys.ScreensImpl.showFromNavigation(ScreensImpl.java:458) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.menu.MenuItemCommands$ScreenCommand.run(MenuItemCommands.java:266) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.menu.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:272) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.menu.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:257) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.component.mainwindow.impl.SideMenuImpl$MenuItemImpl.menuSelected(SideMenuImpl.java:587) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.widget.JmixSideMenu$1.menuItemTriggered(JmixSideMenu.java:91) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	... 88 common frames omitted
Caused by: java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter entityId with expected type of class java.util.UUID from query string select e from lazylo_VehicleColor e where e.id = :entityId.
	at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:946) ~[org.eclipse.persistence.jpa-2.7.7-2-jmix.jar:na]
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:611) ~[org.eclipse.persistence.jpa-2.7.7-2-jmix.jar:na]
	at io.jmix.data.impl.JmixQuery$Param.apply(JmixQuery.java:862) ~[jmix-data-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.data.impl.JmixQuery.getQuery(JmixQuery.java:485) ~[jmix-data-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.data.impl.JmixQuery.getSingleResult(JmixQuery.java:148) ~[jmix-data-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.data.impl.JpaDataStore.executeQuery(JpaDataStore.java:996) ~[jmix-data-0.2.0-SNAPSHOT.jar:na]
Caused by: java.lang.reflect.InvocationTargetException: null

Caused by: com.vaadin.v7.ui.Table$CacheUpdateException: Error during Table cache update. Additional causes not shown.

Caused by: java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter entityId with expected type of class java.util.UUID from query string select e from lazylo_VehicleColor e where e.id = :entityId.

	at io.jmix.data.impl.JpaDataStore.load(JpaDataStore.java:199) ~[jmix-data-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.core.impl.DataManagerImpl.load(DataManagerImpl.java:78) ~[jmix-core-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.data.impl.lazyloading.JmixWrappingValueHolder.getValue(JmixWrappingValueHolder.java:72) ~[jmix-data-0.2.0-SNAPSHOT.jar:na]
	at com.company.lazylo.entity.Car._persistence_get_color(Car.java) ~[main/:na]
	at com.company.lazylo.entity.Car.getColor(Car.java:38) ~[main/:na]
	at io.jmix.core.entity.BaseEntityEntry.getAttributeValue(BaseEntityEntry.java:73) ~[jmix-core-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.core.entity.EntityValues.getValue(EntityValues.java:90) ~[jmix-core-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.core.entity.EntityValues.getValueEx(EntityValues.java:121) ~[jmix-core-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.component.data.table.ContainerTableItems.getItemValue(ContainerTableItems.java:116) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.component.table.TableItemWrapper.getPropertyValue(TableItemWrapper.java:81) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.component.table.TableItemPropertyWrapper.getValue(TableItemPropertyWrapper.java:37) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.component.impl.AbstractTable.formatCellValue(AbstractTable.java:1246) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.widget.JmixTable.formatPropertyValue(JmixTable.java:354) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at io.jmix.ui.widget.JmixTable.getPropertyValue(JmixTable.java:269) ~[jmix-ui-0.2.0-SNAPSHOT.jar:na]
	at com.vaadin.v7.ui.Table.parseItemIdToCells(Table.java:2371) ~[vaadin-compatibility-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.v7.ui.Table.getVisibleCellsNoCache(Table.java:2219) ~[vaadin-compatibility-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	at com.vaadin.v7.ui.Table.refreshRenderedCells(Table.java:1762) ~[vaadin-compatibility-server-8.9.2-5-jmix.jar:8.9.2-5-jmix]
	... 111 common frames omitted

Unexpected error occurs when creating an entity generated from MSSQL database

bomVersion = '1.0.0-SNAPSHOT'

For QA: check also case from #56

  1. Connect to MSSQL server using a third-party program and execute sql script instnwnd.sql from https://github.com/microsoft/sql-server-samples/tree/master/samples/databases/northwind-pubs (or use already created database Northwind in company server)
  2. Create data store and connect it to this database
  3. Click Generate model, refresh list
  4. Select Region -> Next -> Next -> Finish
  5. Run the app (ignore all changelogs in this database if it appears)
  6. Open Region browser
  7. Click Create
  8. Put some string to Region description
  9. Click OK

AR: Unexpected error occurs
SQLServerException: Violation of PRIMARY KEY constraint 'PK_Region'. Cannot insert duplicate key in object 'dbo.Region'. The duplicate key value is (1).

com.microsoft.sqlserver.jdbc.SQLServerException: Violation of PRIMARY KEY constraint 'PK_Region'. Cannot insert duplicate key in object 'dbo.Region'. The duplicate key value is (1).

see stacktrace SQLServerException.txt

If you generate a creation script and use it to create a new table, then there is no such error for the generated new entity.
Therefore, it is not a matter of defining the table, but of constraints, keys, and so on.

Sample project: testlqpreview.zip

ER: create an entity without errors

Cause

Sequences are not generated for entity, so Integer/Long ids for new entities have the same values as in existed records, that leads to conflict.

Possible solutions

  1. Generate sequences too.
    Potential problem: sequence name is built by entity name and becomes invalid in case of changing entity metaclass name or creating ancestor entity using the same table.
    Solution: Set sequence name explicitly in @JmixGeneratedValue#sequenceName (seems to be not working now, migrate this feature from CUBA)
  2. Provide instrument for sequence generation by entity and existing data in database.
  3. Propose to select one of existing sequences

Compatibility with JTA global transactions

Progress

2021-04-13: 15%
2021-04-19: 25%
2021-04-26: 40%
2021-05-11: 70%
2021-05-17: 85%
2021-05-24: 90%

  • Investigate possible JTA configurations
  • Check events and synchronisations
  • Investigate possible implementations
  • Create some kind of API
  • Test coverage
  • Dependencies and starters

Liquibase changelog file generation should not use work directory

Changes

  • Liquibase master changelog stored in memory now.
  • Spring boot version updated: 2.4.0 -> 2.4.2
  • Liquibase version updated: 3.10.3 (spring boot dependency version) -> 4.2.2

QA Notes:

  1. Create application,
  2. add some entities,
  3. run.

ER:

  • eihter no *liquibase-changelog.xml created in work dir. (jmix.core.workDir property, usually it is .jmix/work) or whole .jmix/work is absent while jmix.core.workDir is not overriden in application.properties

Dynamic attribute value lost if default value modified at creation

  1. Setup project with dynattr in build.gradle:
    implementation "io.jmix.dynattr:jmix-dynattr-starter"
    implementation "io.jmix.dynattr:jmix-dynattr-ui-starter"

  1. Create dynamic attribute with default value
    изображение.png
  2. Try to change default value at entity creation
    изображение.png

ER:

  • changed value set to attribute

AR:

  • attribute is empty (while it is not in entity log because it has been written before saving to db and loosing value)
    изображение.png

P.S. 1) Not modified default value saved without problems, 2) changing attribute value for existing instance works fine.

Additional: fix also jmix-projects/jmix-old#448 (comment)

Liquibase cannot find changelog files from base modules on JDK 11

See in the log on the app start:

2020-11-06 18:37:07.574  WARN 3509 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/Users/knst/.m2/repository/io/jmix/security/jmix-security-data/0.2.0-SNAPSHOT/jmix-security-data-0.2.0-SNAPSHOT.jar!/io/jmix/securitydata/liquibase/changelog/
2020-11-06 18:37:07.576  WARN 3509 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/Users/knst/.m2/repository/io/jmix/security/jmix-security-data/0.2.0-SNAPSHOT/jmix-security-data-0.2.0-SNAPSHOT.jar!/io/jmix/securitydata/liquibase/changelog/001-security-data.xml
2020-11-06 18:37:07.592  WARN 3509 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/Users/knst/.m2/repository/io/jmix/ui/jmix-ui-data/0.2.0-SNAPSHOT/jmix-ui-data-0.2.0-SNAPSHOT.jar!/io/jmix/uidata/liquibase/changelog/
2020-11-06 18:37:07.592  WARN 3509 --- [           main] i.s.SpringLiquibase$SpringResourceOpener : Not a valid resource entry: jar:file:/Users/knst/.m2/repository/io/jmix/ui/jmix-ui-data/0.2.0-SNAPSHOT/jmix-ui-data-0.2.0-SNAPSHOT.jar!/io/jmix/uidata/liquibase/changelog/001-ui-data.xml

NPE in JpaLazyLoadingListener on browser screen opening

Sample project: lazyloading (1).zip

  1. Open the Application -> TemplateReport browser.
  2. Create a TemplateReport
  3. Open the Application -> EmailTemplate browser.
  4. Click Create and fill values:
    а) Name и Code
    b) Email body report (there will be the only one, created at step 2)
  5. Save
  6. Close and open the EmailTemplate browser screen

AR: NPE:

java.lang.NullPointerException
	at io.jmix.data.impl.lazyloading.JpaLazyLoadingListener.replaceValueHoldersInternal(JpaLazyLoadingListener.java:125)
	at io.jmix.data.impl.lazyloading.JpaLazyLoadingListener.replaceValueHolders(JpaLazyLoadingListener.java:100)
	at io.jmix.data.impl.lazyloading.JpaLazyLoadingListener.afterEntityLoad(JpaLazyLoadingListener.java:79)
	at io.jmix.core.datastore.DataStoreAfterEntityLoadEvent.sendTo(DataStoreAfterEntityLoadEvent.java:78)
	at io.jmix.core.datastore.AbstractDataStore.fireEvent(AbstractDataStore.java:307)
	at io.jmix.core.datastore.AbstractDataStore.loadList(AbstractDataStore.java:156)
	at io.jmix.core.impl.DataManagerImpl.loadList(DataManagerImpl.java:91)
	at io.jmix.ui.model.impl.CollectionLoaderImpl.load(CollectionLoaderImpl.java:90)
	at io.jmix.ui.component.dataloadcoordinator.OnFrameOwnerEventLoadTrigger.load(OnFrameOwnerEventLoadTrigger.java:48)
	at io.jmix.ui.component.dataloadcoordinator.OnFrameOwnerEventLoadTrigger.lambda$new$0(OnFrameOwnerEventLoadTrigger.java:39)
	at io.jmix.core.common.event.EventHub.publish(EventHub.java:170)
	at io.jmix.ui.screen.Screen.fireEvent(Screen.java:124)
	at io.jmix.ui.screen.UiControllerUtils.fireEvent(UiControllerUtils.java:57)
	at io.jmix.ui.sys.ScreensImpl.fireScreenBeforeShowEvent(ScreensImpl.java:1350)
	at io.jmix.ui.sys.ScreensImpl.show(ScreensImpl.java:362)
	at io.jmix.ui.sys.ScreensImpl.showFromNavigation(ScreensImpl.java:457)
	at io.jmix.ui.menu.MenuItemCommands$ScreenCommand.run(MenuItemCommands.java:266)
	at io.jmix.ui.menu.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:272)
	at io.jmix.ui.menu.SideMenuBuilder$MenuCommandExecutor.accept(SideMenuBuilder.java:257)
	at io.jmix.ui.component.mainwindow.impl.SideMenuImpl$MenuItemImpl.menuSelected(SideMenuImpl.java:587)
	at io.jmix.ui.widget.JmixSideMenu$1.menuItemTriggered(JmixSideMenu.java:91)
 ....

Secure DataManager

Code sample:

@Autowired
@Secure
DataManager secureDataManager;
 
@Autowired
DataManager dataManager;
 
@Autowired
AccessManager accessManager;
 
void load_with_REGISTERED_constraints(Object fooId) {
    Entity entity = secureDataManager.load(Foo.class).id(fooId).one();
}
 
void load_with_REGISTERED_AND_EXPLICIT_constraints(Object fooId) {
    Entity entity = secureDataManager.load(Foo.class).id(fooId).constraints(someExplicitConstraints()).one();
}
 
void load_with_NO_constraints(Object fooId) {
    Entity entity = dataManager.load(Foo.class).id(fooId).one();
}

Infer database type from JDBC URL

Result

The following databases are detected automatically by JDBC DataSource:

  • HSQL
  • PostgreSQL
  • Oracle
  • MySQL
  • MariaDB
  • SQL Server

For SQL Server, two variants are supported:

  • 2008 - a table is used to generate sequences. Set jmix.data.dbmsVersion=2008 to use this option.
  • 2012+ - native sequences are used. Do not set the jmix.data.dbmsVersion for this option.

For custom databases not in the list above, use jmix.data.dbmsType to specify the prefix for DbmsFeatures, DbTypeConverter and SequenceSupport implementations. See for example https://github.com/Haulmont/jmix-db-tests project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.