JPA
- @Entity
- 기본 생성자 필수(public, protected) JPA 를 위한 구현이지만 직접 사용하는 것을 방지하기 위해 protected 접근자로 구현
- The default constructor exists only for the sake of JPA. You do not use it directly, so it is designated as protected.
- 저장할 필드에 final 사용 불가
- 기본 생성자 필수(public, protected) JPA 를 위한 구현이지만 직접 사용하는 것을 방지하기 위해 protected 접근자로 구현
Ref: https://spring.io/guides/gs/accessing-data-jpa/
- Id mapping, property mapping하는데 Setter/Getter 상관 없음
package com.company.prj.mvp.book;
import javax.annotation.processing.Generated;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name = "";
protected Book() {
}
public Book(String name) {
this.name = name;
}
@Override
public String toString() {
return id.toString() + name.toString();
}
}
TEST
package com.company.prj.mvp.book;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.TestPropertySource;
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(properties = "spring.config.location=classpath:application-test.yml")
@Import(BookService.class)
class BookServiceTest {
@Autowired
BookService service;
@Test
@DisplayName("Book 저장하기")
void run1() {
service.create("이게되네");
Book book = service.getById(2);
assertEquals("2이게되네", book.toString());
}
@Test
@DisplayName("Book 가져오기")
void run2() {
Book book = service.getById(1);
assertEquals("1홍길동", book.toString());
}
}
- jpa-hibernate-proxy
- reflect
- http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/0c39a12473c9/src/share/native/java/security/AccessController.c
JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
if (!UsePrivilegedStack) return NULL;
ResourceMark rm(THREAD);
GrowableArray<Handle>* local_array = new GrowableArray<Handle>(12);
JvmtiVMObjectAllocEventCollector oam;
// count the protection domains on the execution stack. We collapse
// duplicate consecutive protection domains into a single one, as
// well as stopping when we hit a privileged frame.
oop previous_protection_domain = NULL;
Handle privileged_context(thread, NULL);
bool is_privileged = false;
oop protection_domain = NULL;
// Iterate through Java frames
vframeStream vfst(thread);
for(; !vfst.at_end(); vfst.next()) {
// get method of frame
Method* method = vfst.method();
// stop at the first privileged frame
if (method->method_holder() == vmClasses::AccessController_klass() &&
method->name() == vmSymbols::executePrivileged_name())
{
// this frame is privileged
is_privileged = true;
javaVFrame *priv = vfst.asJavaVFrame(); // executePrivileged
StackValueCollection* locals = priv->locals();
StackValue* ctx_sv = locals->at(1); // AccessControlContext context
StackValue* clr_sv = locals->at(2); // Class<?> caller
assert(!ctx_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
assert(!clr_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
privileged_context = ctx_sv->get_obj();
Handle caller = clr_sv->get_obj();
Klass *caller_klass = java_lang_Class::as_Klass(caller());
protection_domain = caller_klass->protection_domain();
} else {
protection_domain = method->method_holder()->protection_domain();
}
if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) {
local_array->push(Handle(thread, protection_domain));
previous_protection_domain = protection_domain;
}
if (is_privileged) break;
}
// either all the domains on the stack were system domains, or
// we had a privileged system domain
if (local_array->is_empty()) {
if (is_privileged && privileged_context.is_null()) return NULL;
oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);
return JNIHandles::make_local(THREAD, result);
}
objArrayOop context = oopFactory::new_objArray(vmClasses::ProtectionDomain_klass(),
local_array->length(), CHECK_NULL);
objArrayHandle h_context(thread, context);
for (int index = 0; index < local_array->length(); index++) {
h_context->obj_at_put(index, local_array->at(index)());
}
oop result = java_security_AccessControlContext::create(h_context, is_privileged, privileged_context, CHECK_NULL);
return JNIHandles::make_local(THREAD, result);
JVM_END