JavaEE 更改 SaaS 应用程序的数据库架构运行时
我正在使用JavaEE技术(JPA,EJB,..)
进行多租户开发SaaS应用程序,我选择了“共享数据库,单独模式”方法并设计了数据库( PostgreSQL)就像这样,
基本上我需要做的是更改应用程序中用户会话的默认架构,以便用户可以从
我的业务逻辑的 正确架构中获取自己的数据是用EJB(容器管理),应用服务器是glassfishv3 所以在我的 EJB 中,我只是像这样注入 EntityManager
@PersistenceContext(unitName="DBNAME")
private EntityManager em;
并将事务管理留给 glassfish
我尝试为注入 DataSource 的无状态 EJB 编写 @PostConstruct 回调 但 getClientInfo() 以某种方式返回 null,所以我什至看不到默认架构。我注入 DataSource 的原因是因为我认为我必须做一些低级的事情来指定模式。
我知道如果我管理应用程序中的事务而不是将它们留给应用程序服务器,我可以轻松地通过 EMF 更改 EntityManager 值,但我想保留容器管理的基础架构并仅在运行时更改一些值>
有没有办法用 SessionContext 或其他东西来做到这一点?
解决这个问题的最佳方法是什么?
提前致谢
i am developing a SaaS application by using JavaEE technologies (JPA, EJB, ..)
for multitenancy, i chose 'Shared Database, Separate Schemas' approach and designed the DB (PostgreSQL) like that
basically what i need to do is changing the default schema for user sessions in the application so that users can get their own data from the right schema
my business logic is implemented with EJB (Container-managed) and the app server is glassfishv3
so in my EJBs i am just injecting the EntityManager like this
@PersistenceContext(unitName="DBNAME")
private EntityManager em;
and leaving the transaction management to the glassfish
i tried to write @PostConstruct callbacks for Stateless EJBs injecting DataSource
but getClientInfo() returns null somehow so i can not even see the default schema. The reason why i injected DataSource was because i thought i have to do some low-level stuff to specify the schema.
i know if i manage the transactions in the application instead of leaving them to the app server, i can change the EntityManager values through EMF easily but i wanna keep the Container-managed infrastructure and just change some values at runtime
is there any way to do this with SessionContext or anything else ?
what is the best way of overcoming this issue ?
thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
@PostConstruct
根据定义是错误的方式,因为它只是向 bean 提示它已被构造并且其依赖项已被注入。该 bean 现在位于 EJB 池中等待第一个服务调用。 然后它将连接到该调用的客户端信息。调用之后,客户端信息再次断开。我认为任何类型的标准注入和标准容器管理的持久性内容都不适用于您的情况,因为注入只完成一次(在 EJB 创建时),但您的情况需要为每个服务调用/事务进行注入_AND 您的注入将取决于输入数据 - 包含租户 ID 的客户端请求。
另外:我希望,由于这种方法的维护和性能负担,您最多只有 6 个(左右)租户。我从未见过这种方法在野外工作过。
@PostConstruct
is by definition the wrong way, because it is only a hint to the bean that it has been constructed and its dependencies have been injected. The bean is now in the pool of EJBs waiting for the first service call. Then it will be connected to the client info of that call. After that call the client info is disconnected again.I think any kind of standard injection and standard container managed persistence stuff will not work in your case because injection is done exactly once (at EJB creation time) but your case would require injection for each service call/transaction _AND your injection would depend on input data - the client request containing the tenant id.
Also: I hope, you have only up to 6 (or so) tenants due to the maintenance and performance burden of that approach. I have never seen this approach working in the wild.