2 minute read

  • @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 사용 불가

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

Tags:

Updated: