-
Notifications
You must be signed in to change notification settings - Fork 11
simple DML translation #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
55ab573
c4deaf9
d71f568
1655c57
163fb45
f8edea4
6558ab1
164f433
ed8eb06
3cd06f7
29b740f
8e11fa9
41b1f10
5217cc9
f6bd353
36a7d26
221ced3
826df65
6eb6578
90f8509
9c35cf5
f1cf544
3466624
94a5dfe
aed1a1b
4737f83
a1095e8
56296e6
ea75d2f
5923bb6
1172280
d9bfa71
05f1b4d
7e875eb
7b31d84
2d7ec77
d128182
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,30 +14,32 @@ | |
* limitations under the License. | ||
*/ | ||
|
||
package com.mongodb.hibernate.query.select; | ||
package com.mongodb.hibernate.query; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Table; | ||
import java.math.BigDecimal; | ||
|
||
@Entity(name = "Book") | ||
@Table(name = "books") | ||
class Book { | ||
@Table(name = Book.COLLECTION) | ||
public class Book { | ||
public static final String COLLECTION = "books"; | ||
NathanQingyangXu marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this constant? Currently, tests fail if we change it because the collection name is hardcoded in the test assertions (which is okay, as it keeps the test self-sufficient and clear). I think we could stick to one approach - even if that means some duplication of string literals. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not necessary but still good to have. Either way is fine. But given we have renamed it, we need to change its references in the other testing cases. |
||
|
||
@Id | ||
int id; | ||
public int id; | ||
|
||
// TODO-HIBERNATE-48 dummy values are set for currently null value is not supported | ||
String title = ""; | ||
Boolean outOfStock = false; | ||
Integer publishYear = 0; | ||
Long isbn13 = 0L; | ||
Double discount = 0.0; | ||
BigDecimal price = new BigDecimal("0.0"); | ||
public String title = ""; | ||
public Boolean outOfStock = false; | ||
public Integer publishYear = 0; | ||
public Long isbn13 = 0L; | ||
public Double discount = 0.0; | ||
public BigDecimal price = new BigDecimal("0.0"); | ||
|
||
Book() {} | ||
public Book() {} | ||
|
||
Book(int id, String title, Integer publishYear, Boolean outOfStock) { | ||
public Book(int id, String title, Integer publishYear, Boolean outOfStock) { | ||
this.id = id; | ||
this.title = title; | ||
this.publishYear = publishYear; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright 2025-present MongoDB, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.mongodb.hibernate.query.mutation; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.hibernate.cfg.JdbcSettings.DIALECT; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.doAnswer; | ||
import static org.mockito.Mockito.spy; | ||
|
||
import com.mongodb.hibernate.dialect.MongoDialect; | ||
import com.mongodb.hibernate.query.AbstractQueryIntegrationTests; | ||
import org.hibernate.dialect.Dialect; | ||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; | ||
import org.hibernate.engine.spi.SessionFactoryImplementor; | ||
import org.hibernate.sql.ast.SqlAstTranslator; | ||
import org.hibernate.sql.ast.SqlAstTranslatorFactory; | ||
import org.hibernate.sql.ast.tree.MutationStatement; | ||
import org.hibernate.sql.ast.tree.select.SelectStatement; | ||
import org.hibernate.sql.exec.spi.AbstractJdbcOperationQuery; | ||
import org.hibernate.sql.exec.spi.JdbcOperationQueryMutation; | ||
import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect; | ||
import org.hibernate.sql.model.ast.TableMutation; | ||
import org.hibernate.sql.model.jdbc.JdbcMutationOperation; | ||
import org.hibernate.testing.orm.junit.ServiceRegistry; | ||
import org.hibernate.testing.orm.junit.Setting; | ||
import org.mockito.stubbing.Answer; | ||
|
||
@ServiceRegistry( | ||
settings = | ||
@Setting( | ||
name = DIALECT, | ||
value = | ||
"com.mongodb.hibernate.query.mutation.AbstractMutationQueryIntegrationTests$MutationTranslateResultAwareDialect")) | ||
public class AbstractMutationQueryIntegrationTests extends AbstractQueryIntegrationTests { | ||
NathanQingyangXu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
protected void assertExpectedAffectedCollections(String... expectedAffectedfCollections) { | ||
NathanQingyangXu marked this conversation as resolved.
Show resolved
Hide resolved
vbabanin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assertThat(((MutationTranslateResultAwareDialect) getSessionFactoryScope() | ||
.getSessionFactory() | ||
.getJdbcServices() | ||
.getDialect()) | ||
.capturedTranslateResult.getAffectedTableNames()) | ||
.containsExactlyInAnyOrder(expectedAffectedfCollections); | ||
} | ||
|
||
public static final class MutationTranslateResultAwareDialect extends Dialect { | ||
NathanQingyangXu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private final Dialect delegate; | ||
private AbstractJdbcOperationQuery capturedTranslateResult; | ||
|
||
public MutationTranslateResultAwareDialect(DialectResolutionInfo info) { | ||
super(info); | ||
delegate = new MongoDialect(info); | ||
} | ||
|
||
@Override | ||
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { | ||
return new SqlAstTranslatorFactory() { | ||
@Override | ||
public SqlAstTranslator<JdbcOperationQuerySelect> buildSelectTranslator( | ||
SessionFactoryImplementor sessionFactory, SelectStatement statement) { | ||
return delegate.getSqlAstTranslatorFactory().buildSelectTranslator(sessionFactory, statement); | ||
} | ||
|
||
@Override | ||
public SqlAstTranslator<? extends JdbcOperationQueryMutation> buildMutationTranslator( | ||
SessionFactoryImplementor sessionFactory, MutationStatement statement) { | ||
var originalTranslator = | ||
delegate.getSqlAstTranslatorFactory().buildMutationTranslator(sessionFactory, statement); | ||
var translatorSpy = spy(originalTranslator); | ||
doAnswer((Answer<AbstractJdbcOperationQuery>) invocation -> { | ||
capturedTranslateResult = (AbstractJdbcOperationQuery) invocation.callRealMethod(); | ||
return capturedTranslateResult; | ||
}) | ||
.when(translatorSpy) | ||
.translate(any(), any()); | ||
return translatorSpy; | ||
} | ||
|
||
@Override | ||
public <O extends JdbcMutationOperation> SqlAstTranslator<O> buildModelMutationTranslator( | ||
TableMutation<O> mutation, SessionFactoryImplementor sessionFactory) { | ||
return delegate.getSqlAstTranslatorFactory().buildModelMutationTranslator(mutation, sessionFactory); | ||
} | ||
}; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this class is reusable not only for
select
query but also formutate
query, so it is renamed and moved to more general location. TheBook
class was changed accordingly to go together with it hand in hand.